预处理详解

目录

一:预定义符号

二:#define定义常量

三:#define定义宏

四:带有副作用的宏定义

五:宏的替换规则

六:宏函数的对比

七:# 和 ##

7.1 #运算

7.2 ##预算符

八:命名约定

九:#undef

十:命令行定义

十一:条件编译

十二:头文件的包含 

12.1头文件被包含的方式

12.1.1本地头文件包含

12.1.2库文件的包含

12.2嵌套文件包含

十三:其他预处理指令


一:预定义符号

C语言设置了一些预定义符号,可以直接使用,预定义符号也是在预处理期间处理的。

__FILE__  //进行编译的源文件
__LINE__  //文件当前的行号
__DATE__  //文件被编译的日期
__TIME__  //文件被编译的时间
__STDC__  //如果编译器遵循ASIC C,其值为1,否则未定义

//ASIC C gcc编译器是支持的,但是VS不支持

二:#define定义常量

基础:语法:

#define name stuff
#define MAX 1000      
#define reg register   //为register这个关键字,创建一个更简短的名字

//for循环判断部分什么都不写,表示恒成立,死循环
#define do_forver for(;;) //用更形象的符号来替换一种实现

#define CASE break;case//在case语句自动把break加上

//如果定义的stuff太长,可以分成几行写,除了最后一行,每行的后面都加上一个反斜杠(续行符)
#define DEBUG_PRINT printf("file:%s\tline:%d\t \
                            date:%s\ttime:%s\t, \
                            __FILE__,__LINE__,\     // \后面不能有空格,直接按空格
                            __DATE__,__TIME__)

思考:在define定义标识符时,要不要在最后加上

比如:

#define MAX 1000;
#define MAX 1000

建议不要加上;,这样容易出问题

比如以下场景:

if(condition)
    max = MAX;
else
    max = 0;

如果定义MAX时用第一种加上分号的,等替换了以后就会变成max = MAX;;,if和else之间就是两条语句,而没有大括号的时候,if后面只能有一条语句。这里会出现语法错误。

三:#define定义宏

#define机制包含了一个规定,允许把参数替换到文本中,这种实现通常称为宏(有参数),或者定义宏

下面是宏的申明方式:

#define name(parament-list) stuff
//              参数          内容

其中parament-list是一个由逗号隔开的符号表,它们可能出现在stuff中

注:

参数列表的左括号必须name紧邻。如果两者之间有任何空白,参数列表就会解释为stuff的一部分

举例:

写一个宏,求平方

#define SQUARE(x) x*x

这个宏接受一个参数x,如果上述声明以后,你把SQUARE(5)置于程序中,预处理器就会用下面这个表达式替换上面的表达式:5*5

警告:

这个宏存在一定的问题:

看下面的代码段:

int a = 5;
printf("%d\n", SQUARE(a+1) );//宏的参数不计算,直接传到表达式中

第一眼时,也许大多数人认为就是5+1=6,算的是6的平方,结果是36啊

但是结果是11,这是为什么呢?

替换文本时,参数x被替换成a+1,所以这条语句实际上变成了

printf("%d",a + 1 * a + 1);

这样就可以清晰的看出,由替换产生的表达式并没有按照预想的次序求值。

在宏定义上加上了两个括号,这个问题便轻松解决了:

#define SQUARE(x) (x) * (x)

这样的处理之后就产生了预期的处理

printf("%d",(a+1) * (a+1) );

这里还有另一个宏定义:

算一个数的二倍:

#define DOUBLE(x) (x) + (x)

定义中我们用了括号,避免了之前出现过的问题,但是这个宏可能出现新的错误

int a = 5;
printf("%d" ,10* DOUBLE(a) );

有没有觉得结果是100的?但是实际上打印的结果是55。

替换之后的样子是:

printf("%d", 10*(5)+(5) );

乘法运算大于宏定义,所以出现了55。

这个问题的解决办法是在宏定义表达式两边加上一对括号就可以了。

#define DOUBLE(x) ( (x) + (x) )

提示:

所以用于对数值表达式进行求值的宏定义都应该用这种方式加上括号,避免在使用宏定义时参中的操作符或邻近操作符之间不可预料的相互作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玖剹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值