1.预定义符号
__FILE__ /进行编译的源文件
__LINE__ /文件当前的符号
__DATE__ /文件被编译的日期
__TMIE__ /文件被编译的时间
__STDC__ /如果编译器遵循ANSIC,其值为1,否则表示未定义
eg:
2.#define
#define name stuff
eg:
#define MAX 100
#define reg register //为register这个关键字,创建一个简短的名字
#define do_forever for(; ;)//用for循环语句来替代
#define CASE break; case //方便写case语句时自动填充break
//特别情况如果stuff过长,可以分成几行来写,除最后一行外,其余行加上反斜杠\
#define DEBUGF_PRINT printf(”file:%s\tline"%d\t \
data:%s\ttime:%s\n"\
__FILE__,__LINE__ ,\
__DATE__ ,__TMIE__)
#define定义标识符的时候要不要在最后加上:
#define MAX 100
#dedine MAX 100;
一般情况下,不建议加上,容易出现问题
if(1)
{
max=MAX;
}
else
maxx=0;
这里如果后面加;号的话
就是两个语句max=100; ; 容易报错
3.#define定义宏
在#define机制中包含一条规定,允许吧参数替换到文本中,这种实现称为宏或定义宏
宏的申明方式
#define name(list) stuff
这里要注意左括号必须与name紧挨在一起
如果两者之有空白存在,参数列表会解释成为stuff的一部分
eg:
#define swap(x) x*x
我们传一个参数swap(5)
这里就变成了5*5
那如果是这种状态了
int a=5;
printf("%d",(a+1);
按我们预想结果来看这里应该打印36,实际看下图
那这是为什么呢?这是因为变成了printf(“%d”,a+1*a+1)
那应该如何解决这个问题了,只需要在定义宏哪里x加上括号就行了(x)*(x)
在数值求值时宏定义都应该用这种方式加上括号,避免由于参数中操作符或邻近操作符之间产生与我们所想不一致的结果
4.#define替换规则
- 调用宏时,先对参数进行检查,如果有#define定义的符号,优先被替换
- 替换的文本随后呗插入到原来文本的位置,对于宏来说,参数名被它的值所替换
- 最后,对文本进行扫描,看看是否包含由#define定义的符号,如果有,重复上述步骤
需要注意的是,在宏参数#define中可以出现其他#define定义的符号,但宏不能出现递归
预处理搜索#define定义的符号时,字符串常量里的内容并不被搜索
(1)#和##
从这里我们可以发现字符串由自动连接的特点
#,也能把一个宏参数变成对应的字符串
其中#VALUE处理为“VALUE”
这里介绍一下##的作用
- ##可以把位于它两边的符号合成一个符号
- 允许宏定义从分离的文本片段创建标识符
注意这里要产生一个合法的标识符,否则结果就是未定义的
5.带副作用的宏参数
当宏参数在宏的定义中出现超过一次的时候,如果参数带有副作用,使用这个宏的时候就会产生不可预料的后果,副作用就是表达式求值的时候出现永久性的结果
eg:
x+1;//不带副作用
x++;// 带副作用
x+1的结果
x++的结果