• 带参宏定义


    带参宏定义

    转自:http://blog.csdn.net/swpu_yx32/article/details/52858684

    C语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数,这点和函数有些类似。

    对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。

    带参宏定义的一般形式为:
    #define 宏名(形参列表) 字符串
    在字符串中含有各个形参。

    带参宏调用的一般形式为:
    宏名(实参列表);
    例如:
    #define M(y) y*y+3*y //宏定义
    // Code
    k=M(5); //宏调用
    在宏调用时,用实参5去代替形参y,经预处理宏展开后的语句为k=5*5+3*5。

    其中一定要注意:

    1.宏名和形参列表之间一定一定不能有空格 ----宏定义只是简单的字符替换

    2.形参之后的,字符串最外面一定一定要带上括号;字符串中的形参也一定要带上括号,括号必不可缺

    3、宏定义中do{ }while(0)

       第一眼看到这样的宏时,觉得非常奇怪,为什么要用do……while(0)把宏定义的多条语句括起来?非常想知道这样定义宏的好处是什么,于是google、百度一下了。

        采用这种方式是为了防范在使用宏过程中出现错误,主要有如下几点:

      (1)空的宏定义避免warning:
      #define foo() do{}while(0)
      (2)存在一个独立的block,可以用来进行变量定义,进行比较复杂的实现。
      (3)如果出现在判断语句过后的宏,这样可以保证作为一个整体来是实现:
          #define foo(x)
            action1();
            action2();
        在以下情况下:
        if(NULL == pPointer)
             foo();
        就会出现action1和action2不会同时被执行的情况,而这显然不是程序设计的目的。
      (4)以上的第3种情况用单独的{}也可以实现,但是为什么一定要一个do{}while(0)呢,看以下代码:
          #define switch(x,y) {int tmp; tmp="x";x=y;y=tmp;}
          if(x>y)
            switch(x,y);
          else       //error, parse error before else
          otheraction();
        在把宏引入代码中,会多出一个分号,从而会报错。这对这一点,可以将if和else语句用{}括起来,可以避免分号错误。

    【yasi】错就错在宏展开以后,下面用红色标记的多余的一个分号

    if(x>y)
    {int tmp; tmp="x";x=y;y=tmp;};
    else
    otheraction();


      使用do{….}while(0) 把它包裹起来,成为一个独立的语法单元,从而不会与上下文发生混淆。同时因为绝大多数的编译器都能够识别do{…}while(0)这种无用的循环并进行优化,所以使用这种方法也不会导致程序的性能降低

  • 相关阅读:
    22算法中的O(1), O(n),O(logn), O(nlogn)是什么意思?
    212数据结构队列/优先队列
    02前端项目代码检查规范
    16对element源码进行修改实现上传列表增加上传文件大小显示
    182 尾调用/尾递归/尾递归优化/柯里化函数/蹦床函数
    2.formdata数据格式和json格式的区别
    18柯里化函数/偏函数
    MD5文件验证
    tomcat 部署运行静态html文件
    矩阵快速幂及其简单应用
  • 原文地址:https://www.cnblogs.com/moon-lights/p/7153742.html
Copyright © 2020-2023  润新知