面试题—宏、函数、宏函数、inline函数的区别与联系


--宏和函数:


       。宏其实主要是进行字符串的替换(只是进行字符串的替换,不涉及类型参数),而函数是通过参数的传递,参数是有数据类型的。

       。编译器在预处理阶段就会进行宏的替换,不会进行参数的检查,而函数调用是将值传递给形参(值传递、引用传递、指针传递),在编译阶段之后,执行函数是会对参数进行检查的。


解释:例如:#define  MAX    1000     这个宏在程序的预处理阶段会将所有的字符串MAX直接更改为数据1000,不涉及参数,也不会进行参数的检查。而函数 int MAX(int  num1, int num2);这个函数是通过传值的方式,对参数num1和num2进行int类型的检查。如果类型不匹配,编译器就会报错。 


       。宏的参数不会占用内存空间,因为在预处理阶段时,宏替换已经完成。而函数调用时的参数传递是作为函数的局部变量的,编译器会将函数的参数进行压栈,这样就会占用存储空间。

       。函数调用会花费一定的时空开销,系统在调用函数时,需要保留现场,然后转入被调用的函数中执行,执行完后,在返回到主调函数中继续执行。宏中不需要。


解释:当程序在执行主调函数的时候,如果调用其它函数的时候,就需要先将主调函数先前的执行位置数据记录下来,将数据保存在栈中,同时在执行被调用的函数,需要将被调用函数中的参数(相当于局部变量)压入栈中,执行完被调函数先前压入栈中的局部变量就会出栈,被释放。所以如果返回被调函数的局部变量就会出现错误。这个过程就会花费一部分CPU的时间。



   —内联函数


       。内联函数其实就是将很简单的函数“嵌”到程序中,避免函数调用会花费很长的时间,减少程序运行的时间,提高效率。作为内联函数不能过于复杂,如果过于复杂的话,显示声明函数为内联函数,编译器不一定会将这个函数作为内联函数来处理。其实,对于一个简单的函数(没有复杂的循环等结构)编译器也可能会自动将函数作为内联函数来处理。

        “内联函数不会出现上面花费CPU时间的过程”

     

       。在C++中,如果在类中定义的成员函数,编译器会将其作为内联函数来进行处理,如果在类外定义时,还想将函数作为内联函数,就必须显示的声明。


       。将函数声明为内联函数会提高程序运行的效率。因为内联函数是将函数“嵌”入到程序中,它不会进行函数调用,不会花费函数调用在保留现场、和储存数据的时间。



   —宏函数、函数
       。宏函数会占用大量的空间,因为它采用的方式是进行宏替换,对于一个频繁需要宏替换,需要的空间会明显的增大。函数是消耗时间,在函数调用时,会将所需要的数据进行压栈,需要数据时会进行出栈,cpu就会花费时间,同时进行现场的保护也会花费时间。


例如:

//宏函数

#define ABS(a) ((a) > 0 ? (a) : -(a))
int sum_array(int* x, int n)
{
 int sum = 0;
 for (int i = 0; i < n;)
 {
  sum += ABS(x[i++]);   
  /*寻找错误:
  宏替换会将上一句替换为sum += ((x[i++] > 0 ? (x[i++]) : -(x[i++])));
  这个将会使得i在循环中的一次会增加2,即i = i + 2;使得sum只能求数组中部分元素之和,
  更改后i每次只会+1,下面是更改过后的代码:
  for(int i = 0; i < n; i++)
  {
      sum += ABS(x[i]);
  }
  */
 }
 return sum;
}




本文出自 “无心的执着” 博客,请务必保留此出处http://10740590.blog.51cto.com/10730590/1775431

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值