【面试简答题(详谈)】宏与函数的区别

原创 2016年05月30日 17:14:15

      首先,推荐大家一本书《C与指针》,第14章讲宏讲的非常的详细。

       如:

wKioL1YwzbGQhUWZAALxESQvi_A534.jpg

 

 

宏可以非常频繁地用于执行简单的计算,比如在两个表达式中寻找其中较大(或较小)的一个:

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

为什么不用函数来完成这个任务呢?有两个原因:

     1.用于调用和从函数返回的代码很可能比实际执行这个小型计算工作的代码更大,

所以使用宏比使用函数在程序的规模和速度更胜一筹。

     2.但是更重要的是,函数的参数必须申明为一种特定的类型,所以它只能在类型合适的表达式上使用。

反之,上面的宏可以用于整形、长整形、单浮点型、双浮点型以及其他任何可以使用>操作符比较值大小的类型。

换句话说:

     宏是类型无关的。


     和函数相比,使用宏的不利之处在于每次使用宏时,一份宏定义代码的拷贝将插入到程序中,除非宏非常短,否则使用宏可能会大幅度增加程序的长度。

     还有一些任务根本无法使用函数实现。让我们仔细观察下面的代码:

     #define MALLOC( n,    type)      \

       ( ( type *) malloc ( (n) * sizeof( type ) ) )


        int *pi = MALLOC( 25, int );


这个宏的第二个参数是一种类型,它无法作为函数参数进行传递。

这个宏替换完成之后:

int *pi = ( ( int *) malloc ( (25) * sizeof( int ) ) );

 

 

带副作用的宏参数

     当宏参数在宏定义中出现次数超过一次时,如果这个参数具有副作用,那么当你使用这个宏时就可能出现危险,导致不可预料的结果。副作用就是在表达式求值时出现的永久性效果。例如,下面表达式

   x + 1;

可以执行几百次,他每次获得结果都是一样的,这个表达式不具有副作用。但是

  x ++;    

就有副作用:它增加x的值。当这个表达式下一次执行时,他将产生一个不同的结果。MAX宏可以证明具有副作用的参数所引起的问题。

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

        int x = 5;

        int y = 8;

        int z = MAX( x++, y++);

        printf("x = %d, y = %d, z = %d\n" , x, y, z );


spacer.gif

这里较小的值计算了一次,但是较大的值却计算了两次。


副作用并不仅限于修改变量的值,getchar()也会产生副作用。调用这个函数将”消耗“输入的一个字符。

 

#define 宏的行为和真正的函数相比存在一些不同的地方。spacer.gif



由于有了这些不同之处,所以让程序员知道一个标识符究竟是一个宏还是一个函数式非常重要的。不幸的是,使用宏的语法和使用函数的语法是完全一样的,所以语言本身并不能区分这个两者。

wKiom1YwzomjDC9yAAJJ-xm-45Y689.jpg

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

面试简答题(2)

(1)http状态码含义:

Android面试题目之常见的填空题和简答题

Android面试中常见的填空题和简答题,有些答案仅供参考

面试简答题

书写单例模式。

php面试常见简答题总结

  • 2016-05-12 15:00
  • 147KB
  • 下载

java 面试简答题

  • 2017-08-04 09:56
  • 2.14MB
  • 下载

芯群面试之——C++中宏与内联函数

呵呵,今天在芯群面试时被问到这个题目了,记得之前刚看了宏定义的相关知识,但是在回答时对内联函数有的含糊了。回来找了些资料在总结一下。 内联函数是什么?        内联函数是代码被插入到调用者代码串...

[zz]宏与内联函数(面试常考)

第一部分:宏 为什么要使用宏呢? 因为函数的调用必须要将程序执行的顺序转移到函数所存放在内存中的某个地址,将函数的程序内容执行完后,再返回到转去执行该函数前的地方。这种转移操作要求在转去执行前要保...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)