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浏览一下。