您的位置:首页 > 编程语言 > C语言/C++

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

2015-04-11 11:27 399 查看
原文地址:http://www.programmerinterview.com/index.php/c-cplusplus/inline-vs-macro/

转载地址:http://blog.csdn.net/superbinlovemiaomi/article/details/8609449

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

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

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

[cpp] view
plaincopy

#define SUM(a,b) (a+b)  

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

[cpp] view
plaincopy

// note the use of the 'inline' keyword  

  

inline int sum(int a, int b)  

{  

    return (a+b);  

}  

内联函数和一般函数的区别是,每当编译器遇到一个内联函数的调用时,就写入一个该函数的已编译过的副本。而对于一般的函数,则会产生一个正常的函数调用。

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

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

[cpp] view
plaincopy

#define DOUBLE(X) X*X  

  

 int y = 3;  

 int j = DOUBLE(++y);  

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

[cpp] view
plaincopy

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

  

bool flag = true;  

int j = 5, k = 7;  

  

  

if(flag)  

    ADD_TWO(j,k);  

你很可能会任务宏扩展应该是这样的:

[cpp] view
plaincopy

if(flag)  

{  

    j +=2;  

    k +=2;    

}   

但是实际上if语句只和宏定义的第一个语句结合。实际扩展为:

[cpp] view
plaincopy

if(flag)  

{  

    j +=2;  

}     

      

k +=2;  

如果使用的是内联函数,就不会发生上面的问题了。这是因为内联函数是作为一个单独的语句,整个函数都会和if语句结合。

Debug宏也比较困难。因为预处理器会对宏做文本替换,而这在源代码中是看不出来的。综上所述,相比宏使用内联函数是一个不错的选择。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: