學習筆記總結一
- 第一題 位數輸出
- 第二題 讀入一行字元串
- 第三題 數組遞歸
- 第四題 倍數問題
- 第五題 列印輸出浮點型資料小數點後n位
學習極客時間的人人都能學會的程式設計入門課的知識點總結
第一題 位數輸出
1. 要求:
- 極客時間:人人都能學會的程式設計入門課,第二講,思考題:位數輸出
- 計算一個輸入整數的十進制表示的位數?
- 條件1:允許有多餘輸出的情況下,怎麼實作?
-
條件2:隻允許輸出數字位數的時候,怎麼實作
2. 代碼實作
//代碼來自極客空間課程
#include <stdio.h>
int main() {
long long int n;
scanf("%I64d", &n);
printf(" has %I64d digits\n", printf("%I64d", n)); // 有多餘輸出
char output[50];
int ret = sprintf(output, "%I64d", n);
printf("%I64d\n", ret); // 無多餘輸出
printf("%s", output);
return 0;
}
3. 總結與收獲
- 對于sprintf()和sscanf()函數的幾點新的了解
-
善用傳回值
printf()函數的傳回值為輸出字元的數量,表達錯誤時為負數
sprintf() 傳回值含義 與printf的類似
scanf() 傳回成功指派的資料項數,讀到檔案末尾出錯時則傳回EOF
eg:scanf("%d,%d", &a,&b)
如果ab都成功讀入,那麼scanf的傳回值就是2
如果隻有a成功,傳回值為1
如果都未成功,傳回0
如果遇到錯誤,或遇到end of file 傳回EOF
sscanf() 傳回值與scanf類似
- sscanf和sprintf函數的作用:通過與scanf和printf函數比較來記憶區分
- printf是将格式資料列印在螢幕上,sprintf是将格式資料列印在字元串中。for example:
printf(“%s, %c, %d”, x,y,z); //将xyz的值以逗号隔開的形式列印在螢幕上 sprintf(str, “%s, %c, %d”, x,y,z); //将xyz以逗号隔開的形式寫入到數組str中。
- testcode(printf , sprintf)
#include <stdio.h> int main() { char array[100]; int num = 100; char testChar = 'B'; char charArray[12] = "thank you!"; printf("%s%c%d\n", charArray, testChar, num); sprintf(array, "%s%c%d", charArray, testChar, num); printf("%s", array); return 0; }
- sscanf()函數與scanf()函數類似,都是用于輸入的,前者以固定字元串為輸入源,後者以螢幕為輸入源。
scanf("%d", &x); char s[] = "hello, my friend"; sscanf(s, "%[a-z]", string);//string = hello
- testcode(scanf sscanf)
- printf是将格式資料列印在螢幕上,sprintf是将格式資料列印在字元串中。for example:
-
- 列印printf或者輸入scanf長整型(long long int )時,用格式控制符%I64d來表示
第二題 讀入一行字元串
1. 要求:
- 實作一個讀入一行字元串,并且輸出相關内容的程式,思考如下:
- 條件1:如果字元串中沒有空格,怎麼實作?
- 條件2: 如果字元串中沒有空格,又該怎麼實作?考慮純scanf實作
2. 代碼實作:
//from 極客時間 胡光
#include <stdio.h>
char str[100];
int main()
{
scanf("%[^\n]s", str);
printf("%s\n", str);
return 0;
}
3. 總結與收獲
- 代碼很簡單,重點在于"%[^\n]s"的使用上,其中[]表示一個集合,即輸入的字元串中隻要不是換行符,都正常輸出。
- strlen表示字元串的長度,不包括\0
- sizeof表示求取字元串所占記憶體的大小,包含\0占據的記憶體。
第三題 數組遞歸
1. 要求:
序讀入一個整數n,假設n不會大于1000,請輸出1到n的每一個數字二進制表示中的1的個數
2. 代碼實作
#include <stdio.h>
int main(void){
int array[1001];
int number,i;
scanf("%d", &number);
array[0] = 0;
for(i=1; i<=number; i++){
array[i] = array[i & (i - 1)] + 1;
}
for(i = 1; i<=number; i++){
if(i!=1) printf(" ");
printf("%d", array[i]);
}
printf("\n");
return 0;
}
3. 總結與收獲
- 看似毫無規律可言,可能最開始想到的辦法就是把每一個數字進行統計一遍,換句話說就是判斷該數字末尾的二進制碼是否為1,然後進行移位操作,統計1的個數,雖然可行,但是效率不高,我剛開始就是想這麼做。
- 慢慢發現,類似的問題其本質就是找數學規律,就好像國小時候碰到的算術題,計算0-100的數字的和,有的人就一個一個的加,有的人先看規律,然後很快就算出來了,兩者之間的效率千差萬别。這是一種能力,是可以鍛煉出來的!
- 找規律
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|
0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 |
想用遞歸,就得找出相鄰兩數字之間的練習,可以用前一個數字表示出後一個數字,那現在觀察n和n-1之間的二進制數之間的關系,有兩種情況:
- )如果n的二進制末尾為1(即奇數),則,n-1就是使n的最後一位變為0
- )如果n的二進制末尾為0(即偶數),則,n-1就是使n的最後一位1變為0,之後各位均為1.
- )通過上面的觀察分析,明白了一個共同特點就是n-1讓n最後一位1變成了0,然後将最後一位1之後的0全部變成1,這個時候對比n和n-1就很容易能夠觀察到:n的最後一位1及其後的各位,和n-1對應的位均不相同,這時候引出按位與&的概念并不突兀,也就是n&(n-1)實際上表示的是比n的二進制中1的個數少一個;
- )到這裡,遞歸就派上用場了,假如arry[n]中存儲的是數字n的二進制中1的個數,那麼想知道2的,就得知道2&1的,3的就得先知道3&2的,以此類推,初始條件是知道的,即0的二進制中1的個數是0,那麼遞歸就形成了。
第四題 倍數問題
1. 要求:
題目要求:設計一個去掉倍數的程式
具體内容:
- 讀入兩個整數n和m,其中n的大小不會超過10,m的大小不會超過10000;
- 然後再讀入n個各不相同的正整數,輸出無法被這n個正整數中的任意一個整除的所有數字(範圍:1 - m);
2. 代碼實作
#include<stdio.h>
int main(void){
int array[10001];
int i, j, k;
int valueA,valueB, num;
scanf("%d%d", &valueA, &valueB);
printf("Please enter the number: ");
for(i=0; i<valueA; i++){
scanf("%d", &num);
if(num == 1){
printf("there is no number!\n");
return 0;
}
for(j = num; j <= valueB; j += num){
array[j] = 1;
}
}
for(k=1; k<=valueB; k ++){
if(array[k] != 1)
printf("%d ", k);
}
printf("\n");
return 0;
}
3. 總結與收獲
- 将問題想的複雜了,總是考慮一些最小公倍數,最大公約數之類的東西,可能存在一些好的辦法,但是本末倒置了,首先是按照自己的思路實作出來,再優化也可以。
- 對我來說,問題的最大的難點在于代碼在沒有輸入之前并不知道會有幾個被整除的數字,導緻在所有輸入完成以後,沒辦法準确輸出結果,很大可能會重複輸出。
- 利用數組在輸入每一個整數之後,就對其倍數進行标注,然後最後在輸入完成以後統一進行輸出。
- 是以最後請重視數組的使用。
第五題 列印輸出浮點型資料小數點後n位
1. 要求:要求
題目:列印輸出浮點型資料小數點後n位的程式
要求:
2. 代碼實作
#include<stdio.h>
int main(void){
char string[100];
int num = 0;
double value = 0;
scanf("%lf%d", &value, &num);
sprintf(string, "%%.%dlf\n", num);
printf(string, value);
return 0;
}
3. 總結與收獲
- 了解課程中最後總結的兩點,隻有在自己嘗試動手程式設計,然後遇到問題的時候,才會深刻了解到别人說的話的含義,否則那就隻是一段話而已,永遠也不可能有自己的了解。—來自小白的感悟。
- 了解字元串資訊可以存儲在字元數組中,字元數組就是“變量”,字元串就是“值”;
- sscanf 和 sprintf 函數,本質上在做的是以字元串為中間值,做各種資料類型之間的轉換。