![08bee390b15d7dd1579442b0b0ba0e17.png](https://img-blog.csdnimg.cn/img_convert/08bee390b15d7dd1579442b0b0ba0e17.png)
在C语言中,宏定义的展开处理是在预编译阶段,处理的方式是进行机械的替换。
因此,我们使用宏定义时,如果不慎,可能导致副作用的产生。
下面用两个例子进行解释。
1、不要把宏定义的过程,当成表达式计算的过程
例子是求圆的周长:
#include #define PI 3.14#define RADIUS 2#define DIAMETER RADIUS+RADIUSvoid main(){ printf("Circumference is : %f", PI*DIAMETER);}
圆的半径是2,直径=半径+半径,周长=π×直径,这都是没有错的。
但是上面的程序的运行结果是:
Circumference is : 8.280000
原因分析:在预编译阶段,PI*DIAMETER的展开过程为:
第1步:3.14*RADIUS+RADIUS第2步:3.14*2+2
这显然不是我们要的结果,为了程序能够正常运行,我们需要进行这样的修改:
原来的代码:#define DIAMETER RADIUS+RADIUS修改为:#define DIAMETER (RADIUS+RADIUS)
经过修改后,程序运行正常。
2、不要把函数式宏定义当成函数来使用
例子是求0~9的平方:
#include #define SQUARE(x) ((x)*(x))void main(){ int i = 0; while (i<10) { printf("Squalre is %d", SQUARE(i++)); }}
这个例子和第1个例子比起来,已经吸取教训了,将宏的参数x在宏体中用圆括号包起来。没想到还是中了宏定义副作用的招了。
程序运行结果是:
Squalre is 0Squalre is 6Squalre is 20Squalre is 42Squalre is 72
原因分析:在预编译阶段,宏SQUARE(i++)的展开结果为:
((i++) * (i++))
为了让程序能够正常运行,需要对代码进行如下的优化:
原来的代码:printf("Squalre is %d", SQUARE(i++));修改为:printf("Squalre is %d", SQUARE(i));i++;
修改之后,程序运行正常。
谢谢您的阅读!
#科技新星创作营#