内联函数和宏

出自:http://blog.csdn.net/tianshuai11/article/details/7569659

一,内联函数的用法


  内联函数从源码层层看,有函数的结构,而在编译后,却不具备函数的性质。编译时,类似宏替换,使用函数体替换调用处的函数名。一般在代码中用inline修饰,但是能否形成内联函数,需要看编译器对该函数定义的具体处理。


  inline  Tablefunction(int I)    //是没有效果的,编译器只是把函数作为普通的函 数申明,我们必须定义函数体。
  Inline tablefunction(int I) {return I*I};    // 这样我们才算定义了一个内联函数。我们可以把它作为一般的函数一样调 用。但是执行速度确比一般函数的执行速度要快。


    内联函数必须是和函数体申明在一起,才有效。


【注意】我们也可以将定义在类的外部的函数定义为内联函数,比如:

[html]  view plain copy
  1. Class TableClass  
  2. {  
  3. private:  
  4.   int i,j;  
  5. public:  
  6.   int add() { return i+j;};  
  7.   inline int dec() { return i-j;}  
  8.   int GetNum();  
  9. }  
  10. inline int tableclass::GetNum()  
  11. {  
  12.   return i;  
  13. }  

  
上面申明的三个函数都是内联函数。在C++中,在类的内部 定义了函数体的函数,被默认为是内联函数。而不管你是否有inline关键字。


二,内联函数的应用(可以访问对象的私有成员

     内联函数在C++类中,应用最广的,应该是用来定义存取函数。我们定义的 类中一般会把数据成员定义成私有的或者保护的,这样,外界就不能直接读写我们类成员的数据了。对于私有或者保护成员的读写就必须使用成员接口函数来进行。如果我们把这些读写成员函数定义成内联函数的话,将会获得比较好的效率。

[html]  view plain copy
  1. Class sample  
  2. {  
  3. private:  
  4.   int nTest;  
  5. public:  
  6.   int readtest(){ return nTest;}  
  7.   void settest(int i) {nTest=i;}  
  8. }  
  
  当然,内联函数也有一定的局限性。就是函数中的执行代码不能太多了,如 果,内联函数的函数体过大,一般的编译器会放弃内联方式,而采用普通的方式 调用函数。这样,内联函数就和普通函数执行效率一样了。


三,内联函数注意事项

       1,在内联函数内不允许用循环语句和开关语句。否则编译将该函数视同普通函数

       2,递归函数(自己调用自己的函数)是不能被用来做内联函数的。

       3,内联函数只适合于只有1~5行的小函数。对一个含有许多语句的大函数函数调用和返回的开销相对来说微不足道,所以也没有必要用内联函数实现。 

       4,内联函数的定义必须出现在内联函数第一次被调用之前。 

       5,类结构中所有在类说明内部定义的函数是内联函数。


四,宏的定义

       带参数的宏定义和不带参数的宏定义。具体是指用一个指定的标志符来进行简单的字符串替换或者进行阐述替换。

       宏展开:在c程序编译时将宏名替换成字符串的过程

       #define  max(a,b)   ( (a)>(b) ) ? (a):(b)


五,宏的局限性


  1,宏不能访问对象的私有成员。
  2,宏的定义很容易产生二意性。 


   二义性例子:

  #define TABLE_MULTI(x) (x*x)
  TABLE_MULTI(10)  // 返回100,是正确的。

       TABLE_MULTI(10+10)  //我们期望的结果是400,而宏的调用结果是(10+10*10+10),结果是120


       这显然不是我们要得到的结果。避免这些错误的方法,一是给宏的参数都加上括号。


  #define TABLE_MULTI(x) ((x)*(x))

  这样可以确保不会出错,但是,即使使用了这种定义,这个宏依然有可能出错

       TABLE_MULTI(a++)   //我们本意是希望得到(a+1)*(a+1)的结果,而宏的展开结果: (a++)*(a++)

        如果a的值是4,我们得到的结果是4*4 = 16,a = 6。我们期望得到的是 5*5 = 25


六,内联函数和宏的区别

       宏是由预处理器对宏进行替代,内联函数是编译器控制来实现的。

       内联函数是真正的函数,只是在需要用到的时候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开销。

       你可以象调用函数一样来调用内联函数,而不必担心会产生于处理宏的一些问题。


另外:宏在预处理就进行替换,也就是没有进入编译阶段,所以是无法进行安全检验的。

在递归的函数中用宏的话,效率很低。

内联函数自己也不能递归调用。



#define ADD(x) ((x)+(x))

int x=1;

cout<<ADD(x++)<<endl;   //结果为:2 

cout<<ADD(++x)<<endl;   //结果为:6 

说明是宏定义预处理阶段进行了两次++,最终x=3; 而x++相当于ADD(x), x=x+1;


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值