宏与函数哪家强?

说到宏与函数,我们首先来了解一下它们的定义:

#define定义宏

#define包括一个规定,即允许把某一特定输入根据预定义的规则进行输出,宏即是一种规则与模式,也可以称为语法替换。

函数

在计算机中,函数是一个固定的程序段,也可以成为一个子程序,拥有自己特定的功能,在被调用时将传入的参数进行运算,再返回值给调用它的程序。

在某种意义上,宏与函数都具有将输入给自己的值按照预定义的规则进行预算,再进行输出的功能,那么宏与函数之间谁更胜一筹呢?

首先我们需要了解一个程序是如何转化一个可执行文件的:
在这里插入图片描述
1 .在预处理阶段中,程序进行了注释的删除、将头文件包含进程序、define定义的标识符进行替换。
2.在编译阶段,则对程序中的语法、词法、语意、符号进行分析。
3.在汇编阶段,则是将生成的汇编代码转化为二进制指令,同时形成符号表。
4.在连接阶段、合并段表。符号表,为每个符号表进行重定位。
由此,我们不难看出,#define定义宏早已在预处理阶段就将参数替换了进去,而函数由于需要传参,并返回值,这极大的延长了程序的执行时间,这使得在用户体验的过程中感觉到宏要比函数的执行速度快很多。
那么在其他方面,宏还依然优于函数吗?

●在代码长度方面:由于#define宏会在每次使用时将宏代码插入到程序当中,这使得当宏代码过长时,会极大地增加代码长度;而函数从始至终只有一个,被调用时,仅会传参和返回参数,不会被替换到程序中去,这使得无论函数本身有多麽长,在程序中被调用了多少次,对不会影响程序的代码长度,所以在这点上,函数要优于宏.
●在操作符的优先级上:宏参数的求值是在所有周围表达式的上下文环境,除非给宏参数添加详尽的括号符,否则极易受到周围表达式符号优先级影响,得到与预期结果不符的值!(如下例:),而函数参数则只在调用的时候求值一次,然后将值返回给函数,传参时不易受到周围符号影响,结果更易于预测。在这点上,函数要优于宏。


#include <stdio.h>

#define SQUARE(x)  x*x
#define DOUBLE(x)  (x)+(x)

int main()
{
    int x =6;
    printf("SQUARE =%d\n",SQUARE(x+1));
    printf("DOUBLE=%d\n",10*DOUBLE(x));
    return 0;
}

我们先来看第一个宏“SQUARE(x) x*x”如果你不假思索的认为“SQUARE(x+1)”的值等于49,那你可就大错特错了,将宏参数替换后得到:

printf(“SQUARE=%d\n”,6+1*6+1)

所以最终的值等于13,是不是和想要的值有很大出入呢?
这时你可能会说我将SQUARE(x)定义成(x)*(x)不就可以了吗,的确,在这个宏参数上可以解决,但换一个呢,比如第二个DOUBLE,在对每一项都加了括号后如果在下列的式子中依然会出问题:


printf(“DOUBLE=%d\n”,10*6+6;

答案依然不是我们想要的120,而是66.。。。。
是不是顿时有一股“用宏遍地都是坑的念头”涌上心头T^T…

● 在参数求值上:由于参数每次用于宏定义上时,都会重新求值,所以一些具有副作用的参数如“i++”就会是程序产生预料之外的结果。而参数在被函数被调用前之求值一次,而在函数内部多次使用参数则不会导致这种多次求值的问题,参数的副作用不会导致上述问题的发生。在这点上,函数要优于宏。
● 在参数类型上:宏在调取参数时不会考虑参数的类型,只要对于参数的操作是合法的,宏可以使用任何类型的值。而函数则在声明中已经明确了所需参数的类型,即使参数所执行的任务是形同的,函数也只使用声明中规定的函数类型值。在这点上,宏的适用性更广泛一些,但不对参数的类型进行限制,常常会导致一些安全性的问题,而函数则更加明确与安全,这点上,我个人认为函数要优于宏
● 在书写灵活性上:宏无法定义局部变量,所有宏必须在最外层定义,致使全局可见,而且没有类似namespace的功能,命名时超头疼.(namespace可以让相同命名的函数在不同的namespace中得以共同存在,使用时只需要声明namespace的名称即可,这使得程序员可以在命名不同情况下使用的同一功能的函数时不用绞尽脑汁想一些奇怪的名字,也方便了程序的读写效率),而函数不但可以使用namespace功能,而且可以将函数的主题放在代码的任意区域。所以在这个方面函数更胜一筹。
● 而且,宏无法像函数一样的使用递归!所以在实现循环时,宏与函数高低立见
● 在宏参数被使用时,若遇到#、##便会停止展开,但宏参数往往是先完全展开,再进行传参,这时如果遇到“#”与“##”,势必会造成传参失败,而函数则没有字符限制,在这点上函数依然优于宏。

总结了这么多,希望能帮助到你!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值