C陷阱与缺陷(六)预处理器
2013-03-23 14:40
281 查看
第六章 预处理器
1、不能忽视宏定义中的空格
宏提供了一种对组成C程序的字符进行变换的方式,而并不作用于程序中的对象
#define f (x) ((x)-1)
因为f和后面的(x)之间多了一个空格,所以f代表(x) ((x)-1)
注:这一规则不适用于宏调用,只对宏定义适用
2、宏并不是函数
宏定义中每个参数用括号括起来,最后整个结果表达式也用括号括起来
目的:预防宏展开后因为优先级引起的计算错误
宏定义中尽量避免++等运算,容易引起副作用
3、宏并不是语句
assert宏,参数是一个表达式,如果表达式为0,就使程序终止执行
带多重if语句时,容易匹配错误
宏assert的正确定义
#define assert ((void) ((e) || _assert_error(_FILE_,_LINE_)))
利用了||运算符对两侧的操作数一次顺序求值的性质
4、宏并不是类型定义
最好使用typedef定义类型
#define T1 struct foo *
typedef struct foo *T2;
从定义来看,两者概念完全一致
但是当声明多个变量时,就出错了!
T1 a,b;
T2 a,b;
第一个声明被扩展为struct foo * a,b;
这个语句中a被定义为一个指向结构的指针,而b却被定义为一个结构
第二个声明中a和b都是指向结构的指针
1、不能忽视宏定义中的空格
宏提供了一种对组成C程序的字符进行变换的方式,而并不作用于程序中的对象
#define f (x) ((x)-1)
因为f和后面的(x)之间多了一个空格,所以f代表(x) ((x)-1)
注:这一规则不适用于宏调用,只对宏定义适用
2、宏并不是函数
宏定义中每个参数用括号括起来,最后整个结果表达式也用括号括起来
目的:预防宏展开后因为优先级引起的计算错误
宏定义中尽量避免++等运算,容易引起副作用
3、宏并不是语句
assert宏,参数是一个表达式,如果表达式为0,就使程序终止执行
带多重if语句时,容易匹配错误
宏assert的正确定义
#define assert ((void) ((e) || _assert_error(_FILE_,_LINE_)))
利用了||运算符对两侧的操作数一次顺序求值的性质
4、宏并不是类型定义
最好使用typedef定义类型
#define T1 struct foo *
typedef struct foo *T2;
从定义来看,两者概念完全一致
但是当声明多个变量时,就出错了!
T1 a,b;
T2 a,b;
第一个声明被扩展为struct foo * a,b;
这个语句中a被定义为一个指向结构的指针,而b却被定义为一个结构
第二个声明中a和b都是指向结构的指针
相关文章推荐
- 《C陷阱与缺陷》学习笔记总结:词法陷阱、语法陷阱、语义陷阱,连接、库函数、预处理器、可移植性缺陷及其他
- c缺陷与陷阱笔记-第六章 预处理器
- 【C陷阱和缺陷】预处理器
- 【C陷阱和缺陷】预处理器
- C陷阱与缺陷第六章 预处理器
- 【转】《C陷阱与缺陷》学习笔记(下):连接、库函数、预处理器、可移植性缺陷及其他
- C陷阱与缺陷总结
- C陷阱与缺陷(二)
- C与指针、C陷阱与缺陷
- c陷阱和缺陷学习笔记
- C陷阱与缺陷(八)建议
- 读书笔记--C陷阱与缺陷(四)
- c缺陷与陷阱笔记-第四章 连接
- C陷阱与缺陷-变量的定义位置
- C语言陷阱和缺陷
- 读C陷阱与缺陷笔记(第四章)
- 读书笔记 · C陷阱与缺陷 · 第1章 词法“陷阱”
- C陷阱与缺陷之(一)
- c陷阱与缺陷 语法陷阱有感
- 重读C陷阱与缺陷