zoukankan      html  css  js  c++  java
  • C语言中宏定义(#define)时do{}while(0)的价值(转)

    C语言中宏定义(#define)时do{}while(0)的价值

    最近在新公司的代码中发现到处用到do{...}while(0),google了一下,发现Stack Overflow上早有很多讨论,总结了一下讨论,加上自己的理解,do{...}while(0)的价值主要体现在:

    1. 增加代码的适应性

    下面的宏定义没有使用do{...}while(0)

    #define FOO(x) foo(x); bar(x);

    这样宏定义,单独调用不会出现问题,例如:

    FOO(100)

    宏扩展后变成:

    1
    foo(x);bar(x);

     这样调用FOO没有任何问题,但是FOO(x)不能放入控制语句中,例如

    1
    2
    3
    4
    if (condition)
        FOO(x);
    else
        ...;

    经过宏扩展后,变成了

    if (condition)
        foo(x);bar(x);
    else 
        ...;

    这样就导致了语法错误,语法错误并不可怕,在编译阶段就能发现,更致命的是他有可能导致逻辑错误,这种错误编译器发现不了,一出这种问题,程序员就抓狂吧。例如:  

    if (condition)
        FOO(x);

    这段代码经过扩展后变成:

    if (condition)
        foo(x); bar(x);

    这样一来,无论condition是true还是false,bar(x)都会被调用。有没有被这煎熬过的兄弟啊?

    这时候do{...}while(0)的价值就体现出来了,修改一下FOO的定义

    #define FOO(x) do { foo(x); bar(x); } while (0)

    这样FOO,放入控制语句中就没有问题了。

    也许有人说:把foo(x);bar(x)用大括号括起来不就行了吗?比如这样定义:

    #define FOO(x) { foo(x); bar(x); }

    再看下面代码:

    if (condition)
        FOO(x);
    else 
        ...;

    扩展后:

    if (condition)
        {foo(x);bar(x);} ; //注意最后这个分号,语法错误
    else 
        ...;

    照样语法错误;

    2.增加代码的扩展性

    我理解的扩展性,主要是宏定义中还可以引用其他宏,比如:

    #define FOO(x) do{OTHER_FOO(x)} while(0)
    这样我们不用管OTHER_FOO是但语句还是符合语句,都不会出现问题

    3.增加代码的灵活性

     灵活性主要体现在,我们可以从宏中break出来,例如下面的定义:

    复制代码
    #define FOO(x)  do{ 
        foo(x);  
        if(condition(x)) 
            break; 
        bar(x) 
        ..... 
    } while(0)
    复制代码
  • 相关阅读:
    JAVA基础——编程练习(二)
    JAVA基础——面向对象三大特性:封装、继承、多态
    JVM内存
    50. Pow(x, n) (JAVA)
    47. Permutations II (JAVA)
    46. Permutations (JAVA)
    45. Jump Game II (JAVA)
    43. Multiply Strings (JAVA)
    42. Trapping Rain Water (JAVA)
    41. First Missing Positive (JAVA)
  • 原文地址:https://www.cnblogs.com/yasepix/p/5084661.html
Copyright © 2011-2022 走看看