重讀C Primer Plus,記錄遺漏的、未掌握的、不清楚的知識點數組
一、ctype.h頭文件裏包含了一些列用於字符判斷的函數,包括判斷數字、大小寫字母,控制字符,可打印字符等一些列函數以及轉換字母大小寫的字符映射函數。安全
二、C99標準要求編譯器支持至少127層if-else嵌套。函數
三、包含iso646.h頭文件,可使用and、or、not代替 &&、||、!,這是爲了適應世界各地的鍵盤符號。優化
四、 緩衝區分爲徹底緩衝和行緩衝,徹底緩衝在緩衝區滿時清空,行緩衝在遇到換行時清空,例如文件輸入(徹底)和標準輸入(行),緩衝區大小取決於操做系統,512和4096字節是常見的值。spa
五、在多數Unix環境下,用[Ctrl+D]能夠模擬產生一個文件尾信號,用以通知讀取標準輸入的程序已讀取完,可能這也和交互模式下Python用這個快捷鍵關閉交互模式有關。操作系統
六、Unix下的重定向運算符,輸入重定向<,輸出重定向>,兩個運算符能夠組合使用。他們只能夠鏈接可執行文件和數據文件,同類型不能鏈接,同時輸入和輸出不能重定向到一個以上的文件。命令行
七、同時Unix還具備追加數據運算符>>,管道運算符 |,具體用法就要參照Unix相關書籍了,這並非C的一部分。指針
八、注意設置遞歸的結束條件,以及指針的用法,沒有其他須要注意的內容。rest
九、C99標準支持初始化特定項目,如:code
1 int arr[10] = {1,2,3,[5]=31}
未被初始化的項目都將被置爲0。
十、 對於一個二維(多維)數組arr[n][m]而言,arr+1和arr[0]+1是不一樣的。
十一、對於二維數組來講,arr時地址的地 址,要取兩次值才能夠獲得一般的數值。
1 這裏添一句題外話,在《C Primer Plus》第五版中,P267程序清單10.15的代碼和代碼輸出 2 結果不一致,兩個二維數組的下標寫反了。 3 在輸出中: 4 zippo[1][2] 應寫爲 zippo[2][1] 5 *(*(zippo+1)+2) 應寫爲 *(*(zippo+2)+1)
十二、int (*arr)[2] 表示指向一個包含兩個int的數組的指針;
int *arr[2] 表示包含兩個int類型指針的數組,出現這個差異的緣由在於運算符的結合性。
arr[m][n] 等價於 *(*(arr+m)+n)
1三、對於N維數組,int arr[][10][20][30] 等價於 int (*ar) [10][20][30]
第一個方括號中能夠不寫,由於它將被認爲是一個數組的指針,後面的數字則肯定了具體的數據類型,必須填寫。
1四、C99標準支持變長數組,指維數能夠用變量聲明的數組,並非維數可變,在函數參數中省略變量名時,應用星號代替維數,int sum(int, int, int [*][*]);
1五、C99標準支持複合文字,例如(int [2])= {10, 20},由於是匿名變量,因此必須是聲明時馬上使用,或者用指針保存其地址。目前還沒用過這個特性。
1六、用數組的方法初始化一個字符串時,數組尾部未被使用的內存所有被初始化爲\0,並非只有字符串結尾處被賦值\0。
1七、char *m3 = "hello" 和 char m3[] = "hello" 在聲明上做用幾乎相同。不一樣的是,數組名是常量,沒法修改其值,但指針是能夠的。
1 這裏又發現一處本書的錯誤: 2 P285中間偏下的位置 const char *m3[] = "....省略....." 應該爲 3 const char *m3 = "....省略....."
1八、對於char arr[m][n] 和 char* arr[] 來講,前者是一個字符串數組,也是一個矩形數組,然後者是一個字符串類型的指針數組,它其實也是矩形的,但其中存儲的是地址,而字符串存儲在程序用來存儲常量的那部分,因此沒有被浪費掉的空間,可是這些串是不能被修改的。
1九、fgets函數相比gets更加安全,能夠指定讀入的數據長度,遇到換行符也一樣讀入,同時能夠指定從哪個文件讀入,標準輸入UNIX下可指定爲stdin。
20、對於命令行中的參數,操做系統默認以空格劃分一個個字符串,UNIX也容許使用引號把多個單詞集中在一個參數裏,例:
1 repeat "I am hungry" now
2一、字符串轉換爲整數,經常使用atoi,還有atof,atol。複雜的有,strtol,strtoul,strtod,能夠找出第一個非數字字符,而且能夠轉換相應進制,不經常使用。
2二、對於具備文件做用域的變量(即一般所說的全局變量),static代表其連接類型維內部連接,只有這個文件中的函數能夠訪問這個變量。
2三、五種存儲類:
存儲類 | 時期 | 做用域 | 連接屬性 | 聲明方式 |
自動 | 自動 | 代碼塊 | 空 | 代碼塊內 |
寄存器 | 自動 | 代碼塊 | 空 | 代碼塊內,使用關鍵字register |
具備外部連接的靜態 | 靜態 | 文件 | 外部 | 全部函數以外 |
具備內部連接的靜態 | 靜態 | 文件 | 內部 | 全部函數以外,使用關鍵字static |
空連接的靜態 | 靜態 | 代碼塊 | 空 | 代碼塊內,使用關鍵字static |
2四、對於下列代碼:
1 double *ptd = (double*) malloc (30 * sizeof(double))
在C中,類型指派(double*)是可選的,但在C++中必須有,所以使用類型指派可以使程序由C移植到C++更容易。
2五、分配內存時,calloc函數接收兩個參數,而且會將申請到的塊內存所有置爲0,但有些硬件系統浮點值並不所有用0表示。
2六、一個位於*前的const使得指向的數據成爲常量,位於*後的const使得指針成爲常量。
2七、restrict只能用來修飾指針,且這個指針指向的數據塊由該指針初始且惟一訪問,編譯器會將根據這一點,對多條涉及這個指針的運算進行優化。
2八、在C99標準下,有一些舊關鍵字能夠出如今新的位置。
1 void fun(int a1[const], int a2[restrict], int n) 2 void fun(double ar[static 20])