1.
宏
可以采用命令 #define 来定义宏。该命令允许把一个名称指定成任何所需的文本,例如一个常量值或者一条语句。在定义了宏之后,无论宏名称出现在源代码的何处,预处理器都会把它用定义时指定的文本替换掉。
函数
函数是一段可以重复使用的代码,用来独立地完成某个功能,它可以接收用户传递的数据,也可以不接收。接收用户数据的函数在定义时要指明参数,不接收用户数据的不需要指明,根据这一点可以将函数分为有参函数和无参函数。
用宏和函数实现一下比较大小的函数
#define MAX(a,b) (a)>(b)?(a):(b)
int max(int a, int b)
{
return a > b ? a : b;
}
int main()
{
int a = 10,b=20;
int c=max(a, b);
int d = MAX(a, b);
printf("%d %d\n",c,d);
return 0;
}
在主函数中调用看起来两个函数很相似 实现方式其实也差不多
下面看另一段代码
#define PRINT(type,num) printf(#num"的value是"#type"!",num)
int main()
{
int a = 10;
printf("a的value是%d!\n", a);
PRINT(%d, a);
return 0;
}
这就是把输出函数写成宏的形式 如果需要调用多个相似的输出就可以使用宏来实现 而函数是无法做到的 因为函数是无法传 %d 的
顺便介绍一下 # 和 ##
#和一个宏参数(如#a)可以和字符串连起来 就和上面那段函数一样
##可以使两个宏参数连起来成为一个新已经存在的变量 若连起来的参数本不存在就会报错
#define add(a,b) a##b
int main()
{
int a = 1, b = 2, ab = 3;
printf("%d\n",add(a,b));
return 0;
}
最后输出结果是3
总结一下宏和函数区别
1.速度上
宏比函数快 因为函数还多了调用和返回两个额外开销
2.代码长度
宏如果存在多次调用 预编译后 宏的代码就会在函数中出现多次
而函数每次调用就跳到函数里执行
当实现代码长度比较多时 使用函数的话总体长度会小一点
3.关于优先级
因为宏是直接把参数替换的 使用在运算中穿插宏容易产生优先级的问题 而函数的运算比较独立 结果容易预测
#define ADD(a,b) a+b
int add(int a, int b)
{
return a + b;
}
int main()
{
printf("%d\n", 2 * add(2 + 1, 3));
printf("%d\n", 2 * ADD(2 + 1, 3));
return 0;
}
你觉得结果是什么呢?
如果使用宏的时候不注意 就容易引起优先级的问题
如果非要使用宏的话建议给每个参数带上括号
#define ADD(a,b) ((a)+(b))
4.带有副作用的参数
如a++;
#define FUN(sum) (sum+sum)*sum
void fun(int sum)
{
int c = (sum + sum) * sum;
}
int main()
{
int a = 1,b=1;
FUN(a++);
fun(++b);
printf("%d %d",a,b);
return 0;
}
结果
a传入宏和函数都运算了三次 但宏调用次数多就难以预测结果
函数只改变一次
5.关于参数类型
宏对于参数并没有判断 传过去如何类型都直接替换
而函数必须定义参数类型
6.调试
宏在预定义直接替换不方便调试
函数方便调试
7.递归
宏不能递归
函数可以递归