普通函数
#include <stdio.h>
int sq_int(int x)
{
return x*x;
}
double sq_double(double x)
{
return x*x;
}
int main()
{
int n = 9;
double x = 4.5;
printf("%d的平方是:%d\n",n,sq_int(n));
printf("%lf的平方是:%lf\n",x,sq_double(x));
return 0;
}
对于上面的sq_int和sq_double来说,这两个函数的功能相似,如果求其它数据类型的平方根还需要添加对应类型的函数,代码比较冗余。
宏函数
#include <stdio.h>
#define sq(x) ((x)*(x))
int main()
{
int n = 9;
double x = 4.5;
printf("%d的平方是:%d\n",n,sq(n));
printf("%lf的平方是:%lf\n",x,sq(x));
return 0;
}
宏函数会把相应位置的代码做替换。比如说sq(n)会被替换成((n)*(n))。
- 这种替换发生在编译的时候。这样就通过一个宏函数实现了原来多个函数的功能。
- 宏函数不会去做具体的运算,仅作替换。
- 宏函数省略了参数传递、函数调用和函数返回等操作,所以相对于普通函数来说运行速度提高了。
- 宏函数也可以不加参数。
宏函数与逗号表达式
#include <stdio.h>
#define puts_alert(str) {putchar('\a');puts(str);}
int main()
{
int n;
printf("请输入一个整数:");
scanf("%d",&n);
if(n)
puts_alert("这个数不是0.");
else
puts_alert("这个数是0.");
return 0;
}
上述代码经过宏替换之后变成:
if(n)
{putchar('\a');puts("这个数不是0.");};
else
{putchar('\a');puts("这个数是0.");};
可以发现有多余的分号,导致代码报错。
解决方法是利用逗号表达式。
#define puts_alert(str) (putchar('\a'),puts(str))
经过宏替换之后变成:
if(n)
(putchar('\a'),puts(str));
else
(putchar('\a'),puts(str));
这样整个逗号表达式的值都会被计算到。
宏的副作用
要记住宏仅做替换,不做运算。宏的副作用都来源于替换操作。
- 例一:
#define sq(a) ((a)*(a))
当调用sq(a++)的时候,原则上是希望a先求完平方之后再自增。但是宏替换的结果是((a++)*(a++)),这样a就自增了两次。
- 例二:
#define sq (a) ((a)*(a))
当这样在sq和(a)之前多敲一个空格,这时就是普通的宏定义了,sq会被替换成(a) ((a)*(a))。
- 例三:
#define sum(x,y) x + y
z = sum(a,b)*sum(c,d)
上述sum被替换之后就变成了z = a+b*c+d,就会先算乘法后算加法。所以要把宏函数整个用括号括起来。
参考
https://blog.csdn.net/wit_732/article/details/106602503
标签:语言,putchar,函数,puts,int,double,sq,定义 From: https://www.cnblogs.com/bitcuoo/p/17065892.html