(#define)宏可以频繁的用于执行简单的计算。但一般是宏的代码很短,才使用宏,否则使用宏会使程序长度大幅度提升。
函数可以写一些复杂的的计算。
比如下面这个比较大小的两个数字的大小
#include<stdio.h>
#include<windows.h>
#define MAX(a,b) ((a)>(b)?(a):(b))
int main()
{
printf("%d\n", MAX(3,5));
system("pause");
return 0;
}
这里不用函数而用宏的原因有两个:
1.因为使用函数调用比使用宏的工作代价大,所以对于这类程序使用宏比使用函数的速度更快。因为宏只是替换不需要调用,而函数需要调用。
2.宏是与类型无关的。函数的参数使用时必须声明类型,只有类型合法才可以使用。然而,宏可以使用与整型、长整型、单浮点型、双浮点型等等。
还有一些代码是使用函数无法实现的
比如下面这个动态分配空间使用函数是无法实现的:
#include<stdio.h>
#define MALLOC(a, type) \
((type*)malloc((a)*sizeof(type)))//动态申请了10个type类型的空间
int main()
{
int *p = MALLOC(10, int); //給指针p动态分配了10个int类型的空间
free(p);
return 0;
}
因为宏的第二个参数是一个类型,类型可以作为宏的参数进行传递,不可以作为函数的参数进行传递。
#define宏与函数的比较
属性 | #define宏 | 函数 |
代码长度 | 一般是宏的代码很短,才使用宏,否则使用宏会使程序长度大幅度提升。 | 函数的代码只出现在一个地方,每次代用都去那个地方调用。 |
执行速度 | 比函数快 | 函数需要调用,返回值会有开销 |
操作符优先级 | 函数的参数是在周围表达式的上下文的环境里,建议给宏的每个参数带括号 | 函数的参数只在调用时求值一次,他的结果值传递给函数,表达式的结果更容易预测 |
参数求值 | 参数每次用于宏定义时,都进行求值,由于多次求值,带有副作用的参数有可能带来其他意料之外的结果 | 参数在函数被调用前只求值一次,在函数中多次使用参数并不会带来多种求值。 |
参数类型 | 宏与类型无关 | 函数的参数与类型有关 |