带参数的宏
为了进一步扩大宏的应用范围,在定义宏的时候,还可以带参数
一般形式:#define 标识符(参数表) 字符串
带参数宏的作用:在编译预处理时,将源程序中所有标识符替换成字符串,并且将字符串中的参数用实际使用的参数替换。
例子:#define S(a,b) (a*b)/2
上面这个例子则源程序中如果使用了S(3,4),在编译预处理时就会将其替换为(3*4)/2
代码事例:
#define PI 3.14159
#define L(r) 2*PI*(r)
#define S(r) PI*(r)*(r)
void main()
{
int i =5;
printf("%f", S(i));
}
我们来看下此段程序的编译预处理后的结果:
{
int i =5;
printf("%f", 3.14159*(i)*(i));
}
嘿嘿!就是这样子的了!宏其实就是针对我们的源文件做了1个查找替换的工作。
带参宏与函数
大家是不是发现了一个有趣的问题,带参宏是不是和函数很想象啊!嘿嘿!仔细一瞧,真的好像啊!那么我们现在就来分析下带参宏和函数。
效率:带参宏比函数效率高,因为,宏是编译之后把代码嵌进去了,而函数调用需要很多的步骤(比如保存现场,恢复现场等操作),但是宏生存的文件体积大,因为,替换一次宏就需要生存一个相应的代码段,而函数不会,函数只会有1次代码量。例如:
#define PI 3.14159
#define L(r) 2*PI*(r)
#define S(r) PI*(r)*(r)
void main()
{
int i =5;
printf("%f", S(i));
}
我们多次调用宏,我们去看下编译器做了什么工作:
{
int i =5;
printf("%f", 3.14159*(i)*(i));
printf("%f", 3.14159*(i)*(i));
printf("%f", 3.14159*(i)*(i));
printf("%f", 3.14159*(i)*(i));
printf("%f", 3.14159*(i)*(i));
}
可见编译器为我们生成了5段代码。
我们再看看:
#define PI 3.14159
#define L(r) 2*PI*(r)
#define S(r) PI*(r)*(r)
#define go(i) printf("%f", S(i))
void main()
{
int i =5;
go(i);
go(i);
go(i);
go(i);
go(i);
}
编译器生成了以下代码:
{
int i =5;
printf("%f", 3.14159*(i)*(i));
printf("%f", 3.14159*(i)*(i));
printf("%f", 3.14159*(i)*(i));
printf("%f", 3.14159*(i)*(i));
printf("%f", 3.14159*(i)*(i));
}
这样的结果是:可执行代码的体积增加了,但是效率提高了。原因是没有了函数调用的消耗。
带参宏注意的问题:宏名和参数之间不能有空格,否者空格后面的所有字符序列都作为替换的字符串;带参数的宏展开时,只做简单的字符和参数的替换,不进行任何的计算机操作。所以一般定义宏的时候,一定要加上小括号。例如2*PI*(r).如果没有小括号,在某些时候就会得出错误的结果。例如:#define L(r) 2*PI*r 如果源程序是L(2+3),那么编译预处理后的结果为:2*3.14159*2+3;例如:
#define L(r) 2*r
#define S(r) r*r
void main()
{
printf("%d", S(6-4));
}
这段代码,我们会想到输出的结果为4.但是真正的输出结果呢,为-22.为什么会这样呢?!我们看看编译预处理后的代码:
{
printf("%d", 6-4*6-4);
}
嘿嘿!大家知道原因了吧!所以一定养成写小括号的习惯哦!
带参宏也可以当化妆品用:
嘿嘿!我们看以下代码:
#define IF(r) if(r)
#define THEN {
#define ELSE }else{
#define ENDIF }
#define PRINT(S) printf(s);
#define DIM
#define INT int
void main()
{
DIM INT a =6;
IF(a%2==0) THEN
PRINT("偶数\n")
ELSE
PRINT("奇数\n")
ENDIF
}
哈哈!现在看起来这个C程序是不是怪模怪样的啊!然后我们看这段代码的编译预处理后的代码:
{
int a =6;
if(a%2==0) {
printf(s);
}else{
printf(s);
}
}
学到现在,编译预处理还有,文件包含和条件编译的章节!加油啊!!!