zoukankan      html  css  js  c++  java
  • C语言中do...while(0)用法小结

    在linux内核代码中,经常看到do...while(0)的宏,do...while(0)有很多作用,下面举出几个:

    本文地址:http://www.cnblogs.com/archimedes/p/do-while-0.html,转载请注明源地址。

    1、避免goto语句:

    通常,如果一个函数开始要分配一些资源,然后如果在中途遇到错误则要退出函数,当然,退出前要释放资源,我们的代码可能如下: 

    #defien N 10
    
    bool Execute()
    {
       // 分配资源
       int *p = (int *)malloc(N * sizeof(int));
       bool bOk = true;
    
       // 执行并进行错误处理
       bOk = func1();
       if(!bOk) 
       {
          free(p);   
          p = NULL;
          return false;
       }
    
       bOk = func2();
       if(!bOk) 
       {
          free(p);   
          p = NULL;
          return false;
       }
    
       bOk = func3();
       if(!bOk) 
       {
          free(p);    
          p = NULL;
          return false;
       }
    
       // ..........
    
       // 执行成功,释放资源并返回
        free(p);   
        p = NULL;
        return true;
    }
    View Code

    这里最大的问题是代码冗余,每增加一个操作,就要做相应的错误处理,非常不灵活,于是想到了一下的goto:

    #defien N 10
    
    bool Execute()
    {
       // 分配资源
       int *p = (int *)malloc(N * sizeof(int));
       bool bOk = true;
    
       // 执行并进行错误处理
       bOk = func1();
       if(!bOk) goto errorhandle;
    
       bOk = func2();
       if(!bOk) goto errorhandle;
    
       bOk = func3();
       if(!bOk) goto errorhandle;
    
       // ..........
    
       // 执行成功,释放资源并返回
        free(p);   
        p = NULL;
        return true;
    
        errorhandle:
        free(p);   
        p = NULL;
        return false; 
    }
    View Code

    代码冗余是解决了,但是引入了C语言中比较微妙的goto语句,虽然正确的使用goto语句可以大大提高程序的灵活性与简洁性,但是会使我们的程序捉摸不定,为了既避免使用goto语句,又能消除代码冗余,可以考虑使用下面的 do...while(0):

    #defien N 10
    
    bool Execute()
    {
        //分配资源
        int *p = (int *)malloc(N * sizeof(int));
        bool bOK = true;
    
    
        do {
            //执行并进行错误处理
            bOK = fun1();
            if(!bOK) break;
    
            bOK = fun2();
            if(!bOK) break;
    
            bOK = fun3();
            if(!bOK) break;
    
            //.........
        }  while(0);
    
        //释放资源
        
        free(p);
        p = NULL;
        return bOK;
    }
    View Code

    2、避免空声明在编译时出现警告:

    在linux内核源代码中,经常看到如下宏以避免在编译时出现警告:

    #define FOO do { } while(0)

    3、编写符合习惯的代码块:

    你可能经常会使用如下的宏:

    #define exch(x,y) { int tmp; tmp=x; x=y; y=tmp; }

    然而在某些情况下将会失效,下面的代码使用if...else...

    if (x > y)
            exch(x,y);          // 分支 1
    else  
            do_something();     // 分支 2

    但是将被解释为一个分支的if语句:

    if (x > y) {     
            int tmp;            
            tmp = x;            
            x = y;
            y = tmp;
    }
    ;                           // 空语句
    else                        // ERROR!!! 
            do_something();

    错误出在“;”直接位于代码块的后面,解决的办法是将代码嵌入do...while(0),于是得到下面的代码:

    if (x > y)
            do {
                    int tmp;
                    tmp = x;
                    x = y;
                    y = tmp;
            } while(0);
    else
            do_something();

     于是上面的宏可以修改为:

    #define exch(x,y)       do {
                    int tmp;
                    tmp = x;
                    x = y;
                    y = tmp;
            } while(0)

    4、在条件语句中使用复杂的宏:

    假如一个宏包含类似如下几行代码:

    #define FOO(x) 
            printf("arg is %s
    ", x); 
            do_something_useful(x);

    现在想像一下下面的代码:

    if (blah == 2)
            FOO(blah);

    这将解释为:

    if (blah == 2)
            printf("arg is %s
    ", blah);
            do_something_useful(blah);;

    我们就会发现,if语句只作用于printf(), do_something_useful() 没按照愿意一起执行,即没有像你预期的那样被包含在if代码中,于是可以使用如下的代码块:

    if (blah == 2)
            do {
                    printf("arg is %s
    ", blah);
                    do_something_useful(blah);
            } while (0);

    这样上面的宏就可以改为:

    #define  FOO(x) do { 
                     printf("arg is %s
    ", blah);
                    do_something_useful(blah);
             } while (0)
  • 相关阅读:
    破解百度云盘MAC下载限速问题
    win7 磁盘碎片整理
    python语言快捷注释
    PyCharm字体大小调整
    python pip安装requests库总提示:Fatal error in launcher...''
    请求过程中,需要证书认证,这种情况下如何处理
    python post接口测试第一个用例日记
    常用Linux命令
    接口测试意义及实现的方式
    TypeError: unbound method
  • 原文地址:https://www.cnblogs.com/wuyudong/p/do-while-0.html
Copyright © 2011-2022 走看看