`

C语言中do.while(0)用法小结

c 
阅读更多

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

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;
}

这里最大的问题是代码冗余,每增加一个操作,就要做相应的错误处理,非常不灵活,于是想到了一下的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; 
}

代码冗余是解决了,但是引入了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;
}

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\n", x); \
        do_something_useful(x);

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

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

这将解释为:

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

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

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

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

#define  FOO(x) do { \
                 printf("arg is %s\n", blah);\
                do_something_useful(blah);\
         } while (0)

 

 

 

 
 
 

文章来源:http://www.itnose.net/detail/6024252.html
更多文章:http://www.itnose.net/type/54.html

分享到:
评论

相关推荐

    C语言简明教程(中文)

    2.4. C语言中的句子小结..................................................................................................28 2.5. 用C语言写一段话——程序段..................................................

    C语言程序设计.rar

    2.6.7 关于优先级的小结 27 2.7 表达式 28 2.7.1 表达式中的类型转换 28 2.7.2 构成符cast 29 2.7.3 空格与括号 29 2.7.4 C语言中的简写形式 29 第3章 程序控制语句 31 3.1 程序的三种基本结构 31 3.2 数据的输入与...

    c语言(编写程序最佳参考资料)

    3.5.4 字符数据在内存中的存储形式及使用方法... 10 3.5.5 字符串常量... 11 3.5.6 符号常量... 12 3.6 变量赋初值... 12 3.7 各类数值型数据之间的混合运算... 13 3.8 算术运算符和算术表达式... 14 3.8.1 C...

    《班级成绩管理系统》C语言课程设计.doc

    (4)掌握实现循环结构的三种语句while、 do-while.、for 的使用。 (5)掌握函数的定义方法和调用方法。 (6)能够采用模块化思想调试程序。 3. 课题分析: 对一个有N个学生的班级,每个学生有M门课程。该系统实现对班级...

    新概念C语言.李一波(带详细书签).pdf

    18.3.8 存储类别小结 199 18.4 编译预处理 201 18.4.1 宏替换 201 18.4.2 文件包括 204 18.4.3 条件编译(选讲内容) 204 18.5 如何运行一个多文件的程序 207 习题 208 第19章 C++对C的扩充 211 19.1 C++的...

    iPhone应用开发从入门到精通代码

    C 2.0编程语言232.3.1 Objective-C简介232.3.2 Objective-C的发展历史242.4 混用C/C++编程242.5 本章小结252.6 本章练习25第3章 使用苹果公司提供的开发工具263.1 安装Xcode开发工具263.1.1 从操作系统光盘...

    C语言程序设计(PDF格式)

    2.6.7 关于优先级的小结 27 2.7 表达式 28 2.7.1 表达式中的类型转换 28 2.7.2 构成符cast 29 2.7.3 空格与括号 29 2.7.4 C语言中的简写形式 29 第3章 程序控制语句 31 3.1 程序的三种基本结构 31 3.2 数据的输入与...

    谭浩强c语言程序设计

    3.5.4 字符数据在内存中的存储形式及使用方法 41 3.5.5 字符串常量 41 3.5.6 符号常量 42 3.6 变量赋初值 42 3.7 各类数值型数据之间的混合运算 43 3.8 算术运算符和算术表达式 44 3.8.1 C运算符简介 44 3.8.2 算术...

    C语言入门经典(第4版)--源代码及课后练习答案

    1.10 小结 18 1.11 习题 18 第2章 编程初步 19 2.1 计算机的内存 19 2.2 什么是变量 21 2.3 存储数值的变量 21 2.3.1 整数变量 21 2.3.2 变量的命名 25 2.3.3 变量的使用 26 2.3.4 变量的初始化 28 2.3.5 ...

    C语言程序设计标准教程

    scanf函数是一个标准库函数,它的函数原型在头文件“stdio.h”中,与printf函数相同,C语言也允许在使用scanf函数之前不必包含stdio.h文件。scanf函数的一般形式为: scanf(“格式控制字符串”,地址表列); 其中,...

    C语言程序设计(高清PDF)

    2.6.7 关于优先级的小结 27 2.7 表达式 28 2.7.1 表达式中的类型转换 28 2.7.2 构成符cast 29 2.7.3 空格与括号 29 2.7.4 C语言中的简写形式 29 第3章 程序控制语句 31 3.1 程序的三种基本结构 31 3.2 数据的输入与...

    谭浩强 C语言程序设计 教程全书 Word版

    3.5.4 字符数据在内存中的存储形式及使用方法 10 3.5.5 字符串常量 11 3.5.6 符号常量 12 3.6 变量赋初值 12 3.7 各类数值型数据之间的混合运算 13 3.8 算术运算符和算术表达式 14 3.8.1 C运算符简介 14 3.8.2 算术...

    谭浩强 入门c语言教程

    3.5.4 字符数据在内存中的存储形式及使用方法 10 3.5.5 字符串常量 11 3.5.6 符号常量 12 3.6 变量赋初值 12 3.7 各类数值型数据之间的混合运算 13 3.8 算术运算符和算术表达式 14 3.8.1 C运算符简介 14 3.8.2 算术...

    谭浩强版c语言程序设计

    3.5.4 字符数据在内存中的存储形式及使用方法 41 3.5.5 字符串常量 41 3.5.6 符号常量 42 3.6 变量赋初值 42 3.7 各类数值型数据之间的混合运算 43 3.8 算术运算符和算术表达式 44 3.8.1 C运算符简介 44 3.8.2 算术...

    《C语言程序设计》-PDF格式

    2.6.7 关于优先级的小结 27 2.7 表达式 28 2.7.1 表达式中的类型转换 28 2.7.2 构成符cast 29 2.7.3 空格与括号 29 2.7.4 C语言中的简写形式 29 第3章 程序控制语句 31 3.1 程序的三种基本结构 31 3.2 数据的输入与...

    《C语言程序设计》谭浩强

    3.5.4 字符数据在内存中的存储形式及使用方法 41 3.5.5 字符串常量 41 3.5.6 符号常量 42 3.6 变量赋初值 42 3.7 各类数值型数据之间的混合运算 43 3.8 算术运算符和算术表达式 44 3.8.1 C运算符简介 44 3.8.2 算术...

    谭浩强C语言教程Word版

    9 3.5 字符型数据 9 3.5.1 字符常量 9 3.5.2 转义字符 9 3.5.3 字符变量 10 3.5.4 字符数据在内存中的存储形式及使用方法 10 3.5.5 字符串常量 11 3.5.6 符号常量 12 3.6 变量赋...

    c语言程序设计(第三版)

    3.5.4 字符数据在内存中的存储形式及使用方法 10 3.5.5 字符串常量 11 3.5.6 符号常量 12 3.6 变量赋初值 12 3.7 各类数值型数据之间的混合运算 13 3.8 算术运算符和算术表达式 14 3.8.1 C运算符简介 14 3.8.2 算术...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar )

    3.5.4 字符数据在内存中的存储形式及使用方法 41 3.5.5 字符串常量 41 3.5.6 符号常量 42 3.6 变量赋初值 42 3.7 各类数值型数据之间的混合运算 43 3.8 算术运算符和算术表达式 44 3.8.1 C运算符简介 44 3.8.2 算术...

    谭浩强c语言word版

    3.5.4 字符数据在内存中的存储形式及使用方法 41 3.5.5 字符串常量 41 3.5.6 符号常量 42 3.6 变量赋初值 42 3.7 各类数值型数据之间的混合运算 43 3.8 算术运算符和算术表达式 44 3.8.1 C运算符简介 44 3.8.2 算术...

Global site tag (gtag.js) - Google Analytics