2020-07-11

程序翻译

 1. ##

可以把位于它两边的符号合成一个符号,它允许宏定义从分离的文本片段创建标识符。
#define ADD(num,value) x##num+=value
在函数中调用ADD(1,100)时就变为x1+=100,但是在使用前需要先定义x1这一符号,否则将会报错。
在这里插入图片描述

  2. 带副作用的宏参数

当宏参数在宏的定义中出现超过一次的时候,如果参数带有副作用,那么你在使用这个宏的时候就可能出现危险,导致不可预测的后果。副作用就是表达式求职的时候出现永久性效果。
例如:
x+1 //不带副作用
++x //带副作用
即若x=10,x+1后x的值不变,x++后x的值变为11。

**[1]**x++=6,y++=9,6<9,所以输出z=y++,即z=9,此时再执行y++,y=10,所以打印出的值为 6 10 9。
在这里插入图片描述
**[2]**当x=10,y=8时,x++=11,y++=9,11>9,输出z=x++=11,此时再执行x++,x=12,所以打印的结果为12 9 11。
在这里插入图片描述

     3.宏和函数的对比

宏通常被应用于执行简单的运算。比如在两个数中找出较大的一个。
关于宏☞
[1]宏相对于函数的效率较高。
[2]宏与类型无关(不够严谨)。
[3]宏无法调试。
[4]宏可能会带来运算符优先级的问题导致程序容易出错。
[5]宏不能递归

#undef
宏的作用范围为从定义开始往下,我们还可以使用#undef来取消宏作用。
在这里插入图片描述
此时,前面三个M的值为100,但是第四个M未被定义。

 4.命令行定义

我们可以利用宏来实现for循环打印,但是若要改变循环次数,就需要我们每次去改变宏定义的值,所以我们可以在Linux中利用gcc -DM来改变宏,这就是命令行定义。
在这里插入图片描述

 5.条件编译

(按预处理条件能动态实现代码裁剪)
在这里插入图片描述
如果想看调试过程,可以直接输出中间结果,可以用#ifdef DEBUG和#endif,如果定义了DEBUG就可以看到调试结果,如果没有定义,直接输出最终结果,且这里使用宏定义的时候如果没有给DEBUG赋值,则默认为0。这里的before和after可以看到sum加值之前和之后的sum值,如果不想看调试过程,可以直接去掉宏定义#define GEBUG。
在这里插入图片描述
用#ifdef DEBUG、#else和#endif可以来进行分批裁剪,如果定义了DEBUG,则以debug version输出,如果未定义,则以release version输出。

多条件编译
#if DEBUG0

#elif DEBUG1

#endif
如果满足DEBUG0,输出debug0,如果满足DEBUG1,输出debug1,都不满足则输出unknow,如果DEBUG0,DEBUG1都满足,则输出debug1(从上到下)。
用#if判断表达式结果是否为真。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

用#if defined(symbol)[也可写成#ifdef symbol]用来判定宏是否被定义。
这里DEBUG0被定义(0,1都可)所以输出debug0。
在这里插入图片描述
还可以用#ifndef DEBUG0来看宏有没有被定义,如果没有被定义,输出debug0。
在这里插入图片描述

  6.文件包含

在这里插入图片描述
将test.h插入到test1.h时会先判定宏是否被定义,在来定义宏,test2.h再进来时,发现test.h已经被test1.h定义,所以当test2.h进来时不会再拷贝test.h中的内容,所以当comm.h进来时只包含了一份test.h中的内容(条件编译,防止头文件被重复引用)。
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_46657493/article/details/107292889