在编写代码中,用的最多的预处理应该是#define和#include这两个了吧,但预处理不仅限于此。
先来说说几个简单的预处理:
名称 | 作用 |
---|---|
#define | 宏定义 |
#undef | 撤销定义过的宏名 |
#include | 是编译程序将另一个源文件嵌入到带有#include的源文件中 |
#ifdef | 如果有定义 |
#ifndef | 如果无定义 |
#error | 编译程序时,只要遇到#error就会生成一个编译错误提示信息,并停止编译 |
还有#if、#else、#elif、#endif这种,简单点来说,看成C语言中的if-else就可以了(个人感觉是这个意思)
当然,还有一般用在驱动文件中的宏:
__LINE__ //表示正在编译的文件的行号
__FILE__ //表示正在编译的文件的名字
__DATE__ //表示编译时刻的日期字符串
__TIME__ //表示编译时刻的时间字符串
实例:
printk("%s \n",__LINE__);
注意:宏名的书写两边各是两条下划线哦!
1.1 用define宏定义表达式
先来个简单的,定义一年有多少秒
#defind SEC_A_YEAR 60 * 60 * 24 * 365
这样看好像没错,但是不靠谱,在16位系统下有没有溢出的可能?所以我们可以这样修改一下
#defind SEC_A_YEAR (60 * 60 * 24 * 365)UL
括号这东西呀,能不省就不省,反正又不用钱。下面看看两个定义
#defind SQR(x) x*x //求两个数的乘积
#defind SUM(x) (x)+(x) //求两个数的和
首先来看第一个,当x = 5时,自然没有问题。但是当x = 5+3时呢?转换的表达式为:5+3*5+3。这结果还对吗?再来看第二个,这个定义已经接近完美了,但是还有一点美中不足。当我的 x = 5 * 3时,而且代码又写成:SUM(x)*SUM(x)时,转换成表达式为:(5 * 3) + (5 * 3) * (5 * 3) + (5 * 3),结果又不一样了。
所以呀,括号能加上就加上。下面就是比较完善的了:
#defind SQR(x) ((x)*(x)) //求两个数的乘积
#defind SUM(x) ((x)+(x)) //求两个数的和
思考一下:打印 printf(“SUM(x)”) 的结果是什么?
2.2 文件包含
文件包含是预处理的一个重要功能,它可用来把多个源文件连接成一个源文件进行编译,结果将生成一个目标文件。C语言提供include命令来实现文件包含的操作,它实际是宏替换的延伸,有两种格式:
格式1:
#include < filename >
其中,filename为要包含的文件名称,用尖括号括起来,也称为头文件,表示预处理到系统规定的路径中去获得这个文件(即C编译系统所提供的并存放在指定的子目录下的头文件)。找到文件后,用文件内容替换该语句。
格式2:
#include “ filename ”
其中,filename为要包含的文件名称。双引号表示预处理应在当前目录中查找文件名为filename的文件,若没有找到,则按系统指定的路径信息,搜索其他目录。找到文件后,用文件内容替换该语句。
需要强调的一点是:#include是将已存在文件的内容嵌入到当前文件中。
除了上述提到过的预处理指令,还有一个比较特殊的#pragma 预处理。但是我接触的不是很多,就不做过多的阐述了。需要日后学习深究一番才行。