C语言宏和函数的七大区别

目录

1、代码长度

2、执行速度

3、操作符优先级

4、带有副作用的参数 

5、参数类型

6、调试

7、递归

总结


1、代码长度

#define定义宏

每次使用时,宏代码在编译后都会直接被插入到程序中,因此除了非常小的宏之外,程序的长度会大幅度的增加。

函数

函数的代码只出现于一个地方,每次使用这个函数时,都调用函数地址处的同一份代码,不会像#define定义宏那样大幅增加代码长度

2、执行速度

#define定义宏

 宏代码会在编译后完全插入到程序中,因此在程序运行的时候,没有过多的操作,直接运行,因此相较于函数会更快速

函数

因为函数存在复杂的调用,以及返回返回值的额外时间开销,因此相对于宏会更为慢一些

3、操作符优先级

#define定义宏

宏参数的求值是在所有周围表达式的上下文环境里,除非加上括号,否则邻近操作符的优先级可能会产生不可预料的后果(因此建议宏在书写的时候多加一些括号)

 函数

函数参数只在函数调用的时候求值一次,它的结果值传递给函数,因此表达式的求值结果更容易预测。

实例展示 

#include<stdio.h>
//宏定义MUL
#define MUL(x,y) x*y

//函数定义mul
int mul(int x, int y)
{
	return (x * y);
}

int main()
{
	int x = 2;
	int y = 3;
	printf("%d\n", MUL(x + 5, y + 3));
	printf("%d\n", mul(x + 5, y + 3));
	return 0;
}

 输出结果:

 分析:

对于宏,其实质是在编译后替换原文代码,因此在编译后,MUL(x + 5, y + 3)会被直接被替换成x + 5 * y + 3,而x + 5 * y + 3的计算结果为20,但是函数不会出现类似问题,因此实参为x + 5 和    y + 3,他们的结果会赋给形参,即函数mul在运行的时候下= 7, y = 6,因此函数返回结果为42.而我们若将宏加上足够括号就可以避免这个问题,因此希望各位道友可以在使用宏的时候多多加括号

4、带有副作用的参数 

#define定义宏

参数可能被替换到宏体中的多个位置,因此带有副作用的参数求值可能会产生不可预料的结果。(在这里简单阐述一下何为带有副作用的参数,以便大家理解:对于x+1 和++x,x+1是不带副作用的,因为x+1的表达式的结果仅为x的值+1,而++x的表达式的结果不仅为x的值+1,而且x还自身+1,因此++x是带有副作用的参数,相似的还有getchar(),x++等等)

 函数

函数的参数只在传参的时候求值一次,结果更容易控制,同时带有副作用的参数也不会影响多次。

实例展示 

#include<stdio.h>

//宏定义ADD
#define ADD(x,y) ((x)+ (x) + (y))
int main()
{
	int x = 2;
	int y = 3;
	ADD(x++, y++);
	printf("x = %d  y = %d\n", x, y);
	return 0;
}

输出结果:

 分析:

代码经过编译后,ADD(x++, y++)会直接被替换成((x++) + (x++) + (y++)),因此运行程序后,x++运行了两次,因此x的值变为4,y++运行了一次,因此y的值变为4.

因此当宏参数在宏的定义中出现超过一次的时候,如果参数带有副作用,那么当我们使用这个宏的时候就有可能出现危险,导致不可预测的后果,而用函数则不会产生此类后果,因此在使用宏的时候要思考参数是否带有副作用!!

5、参数类型

 #define定义宏

 宏的参数与类型无关,只要对参数的操作是合法的,它就可以使用于任何类型的参数类型,

 函数

 函数的参数是与类型有关的,如果参数的类型不同,就需要不同的函数,即使他们执行的任务是相同的。

参数类型方面的总结

 正是因为 #define定义宏可以使用于任何类型的的参数类型,因此使用起来更为方便,但正是因为没有类型检验,也使得使用起来较为危险,而函数在调用的时候会有参数类型检验,因此使用起来较为麻烦,但使用起来也较为安全,因此希望各位道友在两者之中合理选择。

6、调试

 #define定义宏

 宏是不方便调试的,因为宏是会替换原文代码,而我们在调试的时候无法观察它替换之后的代码,因此调试起来较为麻烦

函数

 函数是方便调试的,因为调试的时候我们可以跳入函数内部进行逐语句调试。

7、递归

 #define定义宏

 宏因为其是替换原文代码,因此其不支持递归。

 函数

 函数是可以实现递归的,因此在需要递归来求解问题的时候只能用函数,不能用递归。


总结

宏和函数在不同使用场景上都各有优缺点,因此希望各位道友在使用的时候可以多想一想,选择使用最合适的,只有合适才是最重要的。

以上就是小编带领大家回顾宏和函数不同的7个方面,制作不易,希望大家可以一键三连。

谢谢!!

猜你喜欢

转载自blog.csdn.net/m0_70322372/article/details/127355442