内联函数与宏

文章讨论了在C语言中使用宏定义和C++中使用内联函数来实现频繁调用的短小函数。宏定义可能导致意外的副作用,如自增操作的错误和类型安全问题。内联函数则在编译时展开,提高了效率,但也可能增加代码体积。内联函数提供了类型检查,且在类中定义的函数默认为内联。
摘要由CSDN通过智能技术生成

对于一个频繁使用的短小函数,在C语言和C++中分别应用什么实现?

C语言通常使用预处理的宏定义#define来代替短函数定义,而C++使用inline内联函数。

宏定义#define代替短函数可能出现的问题,举例说明。

对于#define MAX(a, b) ((a) > (b)?(a):(b))这样一个宏定义,即使我们非常谨慎将所有参数都放在了括号内,但仍然会出些类似以下情况的麻烦:

int a = 1, b = 0;

MAX(a++, b); // 此处被替换成((a++) > (b)?(a++):(b)),a自增了两次
cout << a << " " << endl;

MAX(a++, b+10); // 此处由于前者小于后者,因此a自增了1次

// 此外,对于不同类型数据的比较也没有受到函数调用的类型检查
MAX(a, "Hello")

由此可见,以上这个宏定义是有一些问题的,同普通函数的功能还是有一些差距。如果是普通函数,在比较不同类型数据使还会受到函数调用的类型检查。

为什么要引入内联函数?

引入内联函数是为了提高程序执行的效率。
对于C/C++程序中一个普通函数的调用过程实际上是将程序执行顺序转移到函数所在的内存中某个地址,将该地址的函数程序执行完成之后,再返回转入函数地址之前的内存地址继续执行之后的代码,这一程序执行转移过程就意味着需要在转去函数所在内存地址前保护程序执行现场并记忆当前程序的内存地址,从函数所在内存地址转回后恢复现场并按照记忆地址继续执行
从以上过程分析可得,普通函数的调用需要有一定时间和空间方面的开销,这将影响程序执行的效率。尤其对于一些低代码量但被高频调用的函数体,时空开销在整个跳转过程中占有较大的比例,因此针对这一类函数,解决其效率问题非常重要。
内联函数在很大程度上解决了这个问题,程序编译时,在编译阶段将调用内联函数的表达式直接进行展开。这种办法将不会产生程序执行跳转的问题,减少了跳转的时间开销;但函数表达式展开将会增加目标程序代码量,进而增加空间开销。由此可见,内联函数的使用是以空间换时间的做法,对于短函数而言较小的空间开销换取内存地址频繁跳转的时间开销是值得的。

内联函数与宏定义的区别

  1. 内联函数在编译时展开,宏定义在预编译阶段展开;
  2. 内联函数是函数体嵌入到目标代码中,宏定义是直接做字符串替换;
  3. 内联函数有类型检查等功能而宏定义没有;

内联函数的使用

所有在类的声明中定义的函数将被自动认为是内联函数。
在内联函数中若有循环和递归调用等复杂操作将不被内联。

求点赞!求收藏!求关注!( •̀ ω •́ )✧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Milk_exe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值