读书笔记--C陷阱与缺陷(六)
2017-09-13 21:57
323 查看
第六章
1.预处理器:预处理器先对代码进行必要的转换处理,简化编程者的工作。
它的重要原因有以下两点:
a. 假如要将程序中出现的所有实例都加以修改,但希望只改动程序一处数值,重新编译实现。
预处理器可以做到这点,通过将这个数值设为显式常量。
b. C语言函数调用花销大,希望有一个程序块看上去像函数确没有函数调用的开销。
2.宏定义的空格不能忽视
宏定义只是简单的文本替换,记住这个本质可以避免很多错误。
如: #define f (x) ((x)-1)
上式意思是: f(x)代表((x)-1) 还是 f 代表(x)((x)-1)
正确答案是后者。因为f与(x)之间多了空格;如果想表达前者的意思,应该定义为如下:
#define f(x) ((x)-1)
括号也很重要,否则文本替换后运算会产生歧义。
其实f1的定义是无法通过的,在编译中报错x未定义。
输出:r2=18, r3=8;
因为 r3=(10)-1*2;
所以宏定义的参数最好都用括号括起来!宏调用时的参数不要出现自增自减运算!
3.宏不是类型定义
其实之前章节就说明过使用 typedef 声明类型要由于使用 define;
如:
a,c,d都可以成功的定义为指向结构的指针,但是b却是定义为结构,非指针。
因为 #define struct foo *a, b; b缺少了*
1.预处理器:预处理器先对代码进行必要的转换处理,简化编程者的工作。
它的重要原因有以下两点:
a. 假如要将程序中出现的所有实例都加以修改,但希望只改动程序一处数值,重新编译实现。
预处理器可以做到这点,通过将这个数值设为显式常量。
b. C语言函数调用花销大,希望有一个程序块看上去像函数确没有函数调用的开销。
2.宏定义的空格不能忽视
宏定义只是简单的文本替换,记住这个本质可以避免很多错误。
如: #define f (x) ((x)-1)
上式意思是: f(x)代表((x)-1) 还是 f 代表(x)((x)-1)
正确答案是后者。因为f与(x)之间多了空格;如果想表达前者的意思,应该定义为如下:
#define f(x) ((x)-1)
括号也很重要,否则文本替换后运算会产生歧义。
//#define f1 (x) ((x)-1) #define f2(x) ((x)-1) #define f3(x) (x)-1 int main() { int r1,r2,r3; //r1=f1(10)*2; r2=f2(10)*2; r3=f3(10)*2; printf("%d\n %d\n", r2, r3); return 0; }
其实f1的定义是无法通过的,在编译中报错x未定义。
输出:r2=18, r3=8;
因为 r3=(10)-1*2;
所以宏定义的参数最好都用括号括起来!宏调用时的参数不要出现自增自减运算!
3.宏不是类型定义
其实之前章节就说明过使用 typedef 声明类型要由于使用 define;
如:
#define T1 struct foo * typedef struct foo *T2; T1 a, b; T2 c, d;
a,c,d都可以成功的定义为指向结构的指针,但是b却是定义为结构,非指针。
因为 #define struct foo *a, b; b缺少了*
相关文章推荐
- 读书笔记--C陷阱与缺陷(四)
- C陷阱与缺陷-- 读书笔记一
- 读书笔记--C陷阱与缺陷(二)
- C陷阱与缺陷-- 读书笔记一
- C陷阱与缺陷 读书笔记
- 读书笔记--C陷阱与缺陷(五)
- C陷阱与缺陷 读书笔记
- (读书笔记)C缺陷与陷阱 第一、二章
- C陷阱与缺陷 —— 读书笔记-3、语义“陷阱”
- 读书笔记--C陷阱与缺陷(一)
- 读书笔记--C陷阱与缺陷(四)
- C缺陷与陷阱读书笔记
- 《C陷阱和缺陷》读书笔记(1)
- 读书笔记--C陷阱与缺陷(七)
- C陷阱与缺陷 读书笔记
- C陷阱和缺陷(C Traps and Pitfalls)-读书笔记
- <C缺陷和陷阱>读书笔记
- 读书笔记 · C陷阱与缺陷 · 第1章 词法“陷阱”
- [读书笔记] C 陷阱与缺陷
- 20100602--C陷阱与缺陷读书笔记大结局(第七章&注意点)