3.1宏定义
3.1.1数值宏常量
从本行宏定义开始,以后的代码就都认识这个宏了。const修饰的数据是有类型的,而define宏定义的数据没有类型,但一定要注意const修饰的不是常量而是readonly的变量,const修饰的只读变量不能用来作为定义数组的维数,也不能放在case关键字后面。
3.1.2字符串常量
宏用来定义字符串时常用来定义路径,定义路径时如果路径中有多个反斜杠且分行定义时,只有后面没任何其它字符的反斜杠是接续符。
3.1.3注释先于预处理指令被处理,所以不能用define宏定义注释符号
3.1.4用define宏定义表达式时有如下规则
a)C的宏只能扩展为用大括号括起来的初始化、常量、小括号括起来的表达式、类型限定符、存储类标识符或do-while-zero结构(尽量少用此结构)
b)函数宏的调用不能缺少参数,如果此函数宏有参数的话。
c)传递给函数宏的参数不能包含看似预处理指令的标记。
d)在定义函数宏时,每个参数实例都应该以小括号括起来,除非它们作为#或##的操作数。#define abs(x) ((x) >= 0 ? (x) : -(x))
e)define预处理操作符只能使用两种标准形式之一。
#define (identifier)
#define identifier
3.1.6#undef
a)宏不能在块中进行#define和#undef
b)不要使用#undef,当它出现在代码中时,能使宏的存在或含义产生混乱
c)尽量使用普通的函数,而不要使用“宏定义函数”,可以减少代码空间的占用(ROM空间)。
d)预处理指令中所有标识符在使用前都应先定义,除了#ifdef和#ifndef指令及defined()操作符。
3.2条件编译
条件编译的功能使得我们可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。这对于程序的移植和调试是很有用的。
所有的#else、#elif和#endif预处理指令应该同与它们相关的#if或#ifdef指令放在相同的文件中。
3.3文件包含
文件包含是预处理的一个重要功能,它将多个源文件链接成一个源文件进行编译,结果将生成一个目标文件。需要强调的一点是:#include是将已存在文件的内容嵌入到当前文件中。include支持相对路径,格式如trackant(蚁迹寻踪):.代表当前目录,..代表上层目录
。
在#include指令的头文件名中不应该出现非标准字符。#include指令后应该紧接着或者”finename”形式的头文件。
3.4#error预处理
#error预处理指令的作用是:编译程序时,只要遇到#error就会生成一个编译错误提示消息,并停止编译。