C 陷阱与缺陷 — 知识地图
原书:C Traps and Pitfalls — Andrew Koenig

目录
| 章节 | 核心主题 |
|---|---|
| 第 1 章 词法陷阱 | 贪心法词法分析、&vs&&、整型字面量进制 |
| 第 2 章 语法陷阱 | 函数指针声明、运算符优先级、悬挂 else |
| 第 3 章 语义陷阱 | 指针与数组、malloc、求值顺序 |
| 第 4 章 链接 | 链接器、extern/static、头文件 |
| 第 5 章 库函数 | getchar 返回值、文件读写、setbuf |
| 第 6 章 预处理器 | 宏的陷阱、typedef vs define |
| 第 7 章 可移植性缺陷 | 整型位宽、负数除法截断 |
🔴第 1 章 词法陷阱
&和|是按位运算符,&&和||是逻辑运算符
词法中的贪心法,编译整体程序识别字符
编译器通常会在内存中开辟一个缓冲区(Buffer),把源代码分块读进去。它维护两个关键指针:
lexeme_beginning(起始指针): 指向当前正在识别的符号的开头。forward(前进指针): 负责向后探测。
起始指针会停留在已经识别的字符的下一个位置,前进指针往后,如果前进指针继续向前,两个指针不能成为一个字符,那么就识别成一个字符,然后起始指针挪移到上一个有效符号结束的下一个位置。
018和18和0x18分别是多大?整形变量问题
开头是0识别为8进制,开头是0x识别为16进制,其余识别为十进制,都转化成2进制补码存储
🔴第 2 章 语法陷阱
1.函数声明与函数指针,请说明 (*(void( * )( ) )0)();如果你不能理解,就点进去
悬挂”else”引发的问题
if(x==0)
if(y==0)error();
else{z=x+y;
f(&z);}
c语言中,else始终与同一括号内最近的未匹配的if结合,实际效果:
if(x==0){
if(y==0)error();
else{
z=x+y;
f(&z);
}
}
🔴第 3 章 语义陷阱
1.指针与数组,二维数组的名称是指向[0][0]的还是指向[0]的?
2.非数组的指针,malloc怎么用的?有3个使用的点还记得吗?
🔴第 4 章 链接
2.声明与定义,extern的意思
extern关键字:extern int a说明了a的存储空间是在程序的其他地方分配的
3.static修饰符的2个作用,你还记得吗
1局部变量:使变量在函数外不能使用,且变为永久性的
2全局变量:使变量只在这个文件生效,防止命名污染
4.头文件
对于声明,可以所有外部对象只在一个地方(.h)声明
然后在使用到这个声明的变量的地方 #include <.h>
定义这个变量的源文件也要包含这个头文件
那么这些声明中只有一个定义,所以是合法的
🔴第 5 章 库函数
返回整数的getchar函数,getchar的返回值能否用char类型的变量接取
🔴第 6 章 预处理器
1.宏不是函数,现代编程规范严禁使用宏来定义类型,应该用typedef
🔴第 7 章 可移植性缺陷
1.int,long之类的到底是几位的,为什么会在”可移植性缺陷”这一章出现?