C++中,内联函数和宏定义的区别是什么?

原文地址:http://www.programmerinterview.com/index.php/c-cplusplus/inline-vs-macro/

这个问题在苹果公司(Apple)和直觉(Intuit)公司面试时都有问到。

内联函数和宏定义的主要区别是不同的处理方式。内联函数由编译器处理,而宏定义则通过C++预处理器展开。这个区别也产生了其他的不同,通过例子可以很好的说明。

C++预处理器通过简单的文本替换来实现宏。假设我们定义了下面的宏:

#define SUM(a,b) (a+b)
当预处理器在代码中遇到SUM(first, last)时,会替换为(first + last)。什么时候会想用宏呢?一般对于简单的函数,为了避免函数调用的额外开销,就会使用宏。记住函数调用会产生开销。
内联函数则直接由编译器解析,而不是预处理器。内联函数和一般的函数很相似。下面是SUM宏的内联函数实现:

// note the use of the 'inline' keyword

inline int sum(int a, int b)
{
	return (a+b);
}
内联函数和一般函数的区别是,每当编译器遇到一个内联函数的调用时,就 写入一个该函数的已编译过的副本。而对于一般的函数,则会产生一个正常的函数调用。

内联函数和宏都是为了消除函数调用的开销。于此同时,代码长度都会增加。记住,内联函数和一般函数很相似,而宏则是文本替换。

事实上,宏在做文本替换时很容易产生bug。假设有下面的定义:

#define DOUBLE(X) X*X

 int y = 3;
 int j = DOUBLE(++y);
如果你认为  将会赋值为4的平方(16),那么恭喜你错了。事实上,文本替换以后,DOUBLE(++y)就扩展为 ++y * ++y,等价于 4 * 5,结果是20。而DOUBLE用内联函数实现时则不会产生这个错误。内联函数只计算一次参数值,因此任何参数计算的副作用只会发生一次。
宏的另一个问题是关于语句结合。假设我们定义的宏有两个语句,然后将其用于 if 语句。如果没有使用大括号,则会像下面这样:

#define ADD_TWO(x,y) x += 2; y +=2

bool flag = true;
int j = 5, k = 7;


if(flag)
	ADD_TWO(j,k);
你很可能会任务宏扩展应该是这样的:

if(flag)
{
	j +=2;
	k +=2;	
} 
但是实际上if语句只和宏定义的第一个语句结合。实际扩展为:

if(flag)
{
	j +=2;
} 	
	
k +=2;
如果使用的是内联函数,就不会发生上面的问题了。这是因为内联函数是作为一个单独的语句,整个函数都会和if语句结合。

Debug宏也比较困难。因为预处理器会对宏做文本替换,而这在源代码中是看不出来的。综上所述,相比宏使用内联函数是一个不错的选择。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值