宏与函数

来源:互联网 发布:江西自考网络助学 编辑:程序博客网 时间:2024/06/05 05:25

宏与函数的一些优劣

一般宏用于执行简单的运算,例如:

#define   MAX(a,b)       ((a) > (b) ? (a) : (b))

这种情况下使用宏比使用函数要好,原因有两点:

1、调用函数要消耗系统一定的额外时间,执行额外的代码(保护处理器现场、数据压栈、函数返回、恢复处理器现场等操作)有可能这些额外的操作比这个小型的计算所消耗的时间更大,所以使用宏比使用函数在程序的规模和速度方面更胜一筹。

2、函数的参数必须声明为一种特定的类型,所以他们只能在特定的类型的表达式中使用,而使用上面的宏则任何只要可以使用“>”来比较大小的类型都可以使用该宏,换句话说,宏是与类型无关的。

与函数相比使用的宏的不利之处在于每次使用宏时,宏定义代码的拷贝都将插入到程序中。除非宏非常的短,否则使用宏将大幅度增加程序的长度

还有一些任务是无法使用函数来实现的,例如下面的宏实现的功能:

#define   MALLOC(n,type)      ((type *)malloc((n) * sizeof(type)))

我们观察一下这个宏的确切工作过程:

pi  =  MALLOC(25,int);

这句语句将会被预处理器替换成下面的语句:

pi  =  ((int *)malloc((n) * sizeof(int)));

而这个功能是无法使用函数来实现的。

 

带副作用的宏参数

所谓副作用就是在表达式求值中出现永久性效果,例如下面的表达式:

x+1;

可以重复出现几百次,它们每次执行的结果都是一样的,这个表达式不具备副作用。但是:

x++;

就具有副作用:它增加x的值,这个表达式在下一次执行时将会产生不同的结果,下面是一个带副作用的宏参数的例子:

#define    MAX(a,b)    ((a)>(b)?(a):(b))

......

x = 5;

y = 8;

z = MAX(x++,y++);

printf("x = %d,  y = %d,  z=%d/n", x,y,z);

函数将输出 x = 6, y =  10, z = 9;

可能初次看这个结果都无法理解,但是别忘了宏的处理方式,将这个宏替换成宏定义代码,这个结果就很明了了。

 

副作用并不仅限于改变变量的值,下面的表达式:

getchar();

注意这个表达式也是有副作用的,调用这个函数将“消耗”输入的一个字符,所以该函数的后续调用将得到不同的字符

 

#define宏的行为和真正的函数相比存在一些不同的地方,但是使用宏的语法和使用函数的语法是完全一样的,所以语言本身并不能帮助你区分两者,这就需要我们自己区分一个常见的约定是将宏的名字全部大写

 

 

原创粉丝点击