C 陷阱与缺陷 — 知识地图

← 学科总览 | ← 主页

原书:C Traps and Pitfalls — Andrew Koenig

1774158263962


目录

章节核心主题
第 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)();如果你不能理解,就点进去

2.符号优先级: !和&谁的优先级更高,忘了就看看

悬挂”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个使用的点还记得吗?

3.数组的和指针的声明,数组名什么时候不能当做指针?

4.求值顺序,y[i]=x[i++];先自增还是先赋值?


🔴第 4 章 链接

1.什么是链接器?

2.声明与定义,extern的意思

extern关键字:extern int a说明了a的存储空间是在程序的其他地方分配的

3.static修饰符的2个作用,你还记得吗

1局部变量:使变量在函数外不能使用,且变为永久性的

2全局变量:使变量只在这个文件生效,防止命名污染

4.头文件

对于声明,可以所有外部对象只在一个地方(.h)声明

然后在使用到这个声明的变量的地方 #include <.h>

定义这个变量的源文件也要包含这个头文件

那么这些声明中只有一个定义,所以是合法的


🔴第 5 章 库函数

返回整数的getchar函数,getchar的返回值能否用char类型的变量接取

更新顺序文件,文件读写能否同时进行?

缓冲输出与内存分配,setbuf库函数的使用方法?


🔴第 6 章 预处理器

1.宏不是函数,现代编程规范严禁使用宏来定义类型,应该用typedef


🔴第 7 章 可移植性缺陷

1.int,long之类的到底是几位的,为什么会在”可移植性缺陷”这一章出现?

2.负数除法取整?


读书笔记 / 重点摘录