空枝|C|深入理解库中随处可见的宏
C预处理器在程序编译之前查看程序(故称之为预处理器) 。 根据程序是的预处理指令 , 预处理器把符号缩写替换成其表示的内容 。 预处理器可以包含程序所需的其他文件 , 可以选择让编译器查看哪些代码 。
预处理指令以#开头 , 到后面的第一个换行符为止 。 也就是说 , 指令的长度仅限于一个逻辑行(预处理前 , 编译器会将多行物理行处理为一个逻辑行) 。
编译器在预处理前的翻译处理:
I 编译器把源代码中出现的字符映射到源字符集 , 包括处理多字节字符和三字符序列 。
II 代码物理行换行的处理 , 编译器定位每个反斜杆后面跟着换行符(按下Enter键在源代码文件中换行所生成的字符 , 而不是指符号表征\n)的实例 , 并删除它们 , 把多个物理行转换成一个逻辑行 。 因为预处理表达式的长度必须是一个逻辑行(一个逻辑行可以是多个物理行) 。
III 编译器把文本划分成预处理记号(token , 由空格、制表符或换行符分隔的项)序列、空白序列(一个空格替换所有空白序列 , 但不包括换行符)和注释序列(用一个空格替换) 。
以上三步后 , 开始进行预处理阶段 。
#define一般用来定义宏 , 做宏替换或头文件的保护性定义 , 分三类:
宏的名称不允许有空格 , 遵循C变量的命名规则 。
替换体也叫替换列表 , 一旦预处理器在程序中找到宏的实例后 , 会用替换体代替该宏 。
从宏变成最终替换文本的过程称为宏展开(macro expansion) 。
#define PRINTX printf("x is %d\n",x)可以理解为:
define a macro, named PRINTX, replaced by printf("x is %d\n",x)
1 宏定义符号常量#define指令可以用来定义明示常量(manifest constant , 也叫符号常量)
下面是使用宏来定义符号常量的实例:
/* simple preprocessor examples */#include #define TWO 2/* you can use comments if you like*/#define OW "Consistency is the last refuge of the unimagina\tive. - Oscar Wilde" /* a backslash continues a definition to the next line */#define FOURTWO*TWO#define PRINTX printf("X is %d.\n", x)#define FMT"X is %d.\n"int main(void){int x = TWO;/* int x = 2;*/PRINTX;/* printf("x is %d\n",x);*/x = FOUR;/* X = TWO*TWO → X = 2*2 只做替换 , 包括循环替换 , 不做计算 */printf(FMT, x);/* printf("X is %d.\n", x); */printf("%s\n", OW); /* printf("%s\n", 2);*/printf("TWO: OW\n");/* 双引号中的字符 , 即使有定义宏 , 也不做替换 , #宏参数例外*/getchar();return 0;}/*X is 2.X is 4.Consistency is the last refuge of the unimaginative. - Oscar WildeTWO: OW*/对于常量(或字面量)替换 , 也可以使用const定义 。 但用作静态数组大小时 , 一些编译器并不支持const定义的常量 。
那么 , 何时使用字符常量?对于绝大部分数字常量 , 应该使用字符常量 。 如果在算式中使用字符常量代替数字 , 常量名能更清楚地表达该数字的含义 。 如果是表示数组大小的数字 , 用符号常量后更容易改变数组的大小和循环次数 。 如果数字是系统代码(如EOF) , 用符号常量表示的代码更容易移植(只需要改变EOF的定义) 。 助记、易更改、可移植 , 这些都是符号常量很有价值的特性 。
2 函数宏(带参数的宏)函数宏(带参数的宏)的定义和使用看起来都像函数 , 都使用圆括号 , 但是两者却完全不同 , 特别是宏参数和函数参数不完全相同(宏参数替换不做计算 , 不求值 , 只替换字符序列) , 使用函数宏还可能会有一些陷阱 。
推荐阅读
- 游戏资讯小驿站|我的世界拔刀剑模组:独特设定!帮助玩家更深入了解刀的制作
- 小机灵鬼|干货速来!透彻剖析微服务架构设计模式,深入开发Java有奇效
- 视听凉都|反对浪费,学校在行动,深入人心:厉行节约
- 巴基斯坦|诱敌深入之计奏效!印一支械步兵连全军覆没,美:早提醒就不听
- 蝙蝠侠|前后十年无人超越,无差评漫改《蝙蝠侠:阿卡姆》为何深入人心?
- 九江视听网|这家高科技投资集团来浔考察,双方就多个领域进行了深入洽谈
- 央美教授刘波:深入浅出,用18个月设计中国警旗
- 空枝|一个漂亮的开源HTML5音乐播放器——APlayer
- 空枝|这台手机,我整整等了三年,终于要发布
- 空枝|华为云手机革新概念、与我书中未来手机革新概念同理
