the C programming language筆記
P16. int getchar()注意用 int 接收 getchar() 傳回的值,也因為可能會傳回EOF(這是個非字元常量)。
ghtP33. 無引數函式宣告或定義是應在引數列表裡註明 void 。如 int main(void)
P38. "hello," "world" 同 "hello,world"
P39. enum 型別支援編譯時檢查,因此常比用 #define 定義常量好些
P51. “in a two's complements number system, x&(x-1) deletes the rightmost 1-bit in x”
P52. int n; float f; (n>0) ? f : n 會返回float型別。
P53. 運算子優先順序和運算方向表。注意單目運算子都是在從右相左運算,還有?:和所有賦值類運算子。?:雖是從右相左,但不會 : 兩邊的都計算。
P53. 不要寫出printf("%d %d", ++n, power(2, n)) 和 a[i]=i++ 這種奇怪的statement,"C, like most languages, does not specify the order in which the operands of an operator are evaluated."
P72. 函式同變數很相似,可以在函式內或結構體內宣告。
P81. 檔案外部宣告,若是陣列可以不宣告大小。extern char str[ ];
P85. external和static變數初始化必須是常量表達式(可以是#define定義的常量,因為#define在編譯最開始就被分析了;所以const常量不行)
P90. #define是用作字串替換的,即替換之前不會做任何處理。# 可以將巨集即刻擴充套件為字串(有雙引號)(#define dprint(str) printf(#str ": error")),## 連線兩個巨集(#define cat(front, rear) front##rear)。
P97. 指標和陣列是不同的型別,雖然他們的很多操作相似和相同。宣告陣列時用的[ ]和表示陣列地址時的[ ]也是不同的,第二個是操作符。
P122. 分析複雜宣告。char (*(*x( ))[ ])( ); char (*(*x[3])())[5];
P149. 有關位域。struct st{int a:1; int b:2;};
P175. Example--An Implementation of fopen and getc.利用unix系統呼叫open creat read write實現帶緩衝的檔案讀寫。比較有意思的有P176和P178中stdin stdout stderr的定義,FILE結構體和_flag列舉型別的定義,用巨集定義getc putc等。
P179. Example--Listing Directories.目錄檔案裡儲存了該目錄下所有檔案的inode和name。P180有目錄結構體和inode的簡單定義。
P185. Example--A Storage Allocator.利用unix系統呼叫sbrk()實現。首先是地址對齊問題(P185下),然後是header定義(地址對齊選了較苛刻的long),最後free實現中相鄰空間合併的處理也有意思。
Appendix. A適合細看,B邊看邊試(有許多好用的函式),C瀏覽一下。