KEIL编译器预处理器和预定义宏(include,ifdef,def等)
“ 原创文章,欢迎分享,转载请注明来源,并给出原始链接,未经书面允许,请勿用于商业用途。”
Keil使用的C编译器支持常用的编译器预定义宏和对文件进行预处理。
在设置界面打开预处理器选项,就可以输出每一个文件对应的预处理文件。当然,你不选择这个选项,编译器也会默认启用预处理编译的,只不过不会对应每一个C文件生成这个预处理结果文件而已。
首先,我们了解一下何为预定义宏和预处理器以及他们起什么作用
预定义宏:ARM编译器预定义了很多宏,这些宏提供了工具链版本号和编译器选项的相关信息。
预处理器:对每一个文件的预处理命令进行预先处理(不是编译),包括包含文件的展开,常量的计算,重复定义的排除等等,简而言之,就是把一个C文件里面包含或者应用的其他文件的信息整合到一个文件,并进行一定的处理。
一,预定义宏
常见的预定义宏如下:
__FILE__: 被编译文件的名称
__LINE__:被编译文件的当前行号
__DATE__: 编译开始的日期
__TIME__: 编译开始的时间
__FILE__,__LINE__宏我们一般用来输出调试信息,以便于检查输出文件的信息位置,其值是一个字符串。
例如:printf(“File:%s,Line:%s,value=%d\n”, __FILE__,__LINE__,number);
通过这个信息输出,我们就清楚的知道,在哪一个文件哪一行,变量number此时的数值是多少。
__DATE__,__TIME__宏,一般组合起来使用,输出一个工程编译信息。
例如:printf(“File:%s,Line:%s \n”, __ DATE __,__ TIME __,);
通过这个信息输出,我们就知道该文件是什么日期和时间编译的。
其他的很少用得到的可以查询KEIL的帮助文档:
二,预处理器
预处理器的作用是处理源文件中发现的命令。
预处理器命令必须放在一行的开头。所有命令都以‘#’为前缀。例如
#include<stdio.h>
#pragma
#define LedOn() 1
常见的预处理命令如下:
define :定义一个预处理器宏或常数
if :计算一个条件编译的表达式
elif :当前面的if ifdef ifndef 或elif分支没有执行发起一个if条件的选择分支
else :当前面的if ifdef 或ifndef分支没有执行 发起一个选择分支
endif :结束一个if ifdef ifndef elif 或else块
error :输出一个由用户定义的错误信息 本命令指示编译器输出指定错误信息
ifdef :计算一个条件编译的表达式 计算的参数是一个定义的名称
ifndef :和ifdef相似 但如果没定义则计算成立
include :从一个外部文件中读源文本,符号序列决定了包含文件的查找顺序,编译器在包含文件目录中查找用大于/小于号“< >”指定的包含文件,在当前目录中查找用双引号“”指定的包含文件
line :指定一个行号和一个可选的文件名,这用在错误信息中来标识错误的位置
pragma : 允许指定可包含在命令行的命令 程序可以在命令行中包含相同的命令
undef : 删除一个预处理器宏或常数定义
我们用下面的一段代码分别演示上面的预处理命令的作用:
//如果不使用这个定义,下面的结构大小12字节,使用后11字节
//压缩后存储空间变少,但是访问变量的指令会变复杂。
typedef struct
{
int mode;
unsigned char hour;
unsigned char minute;
}ALARMITEM;
熟练的掌握这些宏和预处理的使用方法,对我们管理大型项目的文件和灵活运用编译信息将起到非常好的作用。下一章我们再仔细的讲一讲起运用技巧。