#define MACRO_NAME(para) do{macro content}while(0)
的格式,总结了以下几个原因:
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();
在把宏引入代码中,会多出一个分号,从而会报错。
//------------------------------------------------
使用do{….}while(0) 把它包裹起来,成为一个独立的语法单元,从而不会与上下文发生混淆。同时因为绝大多数的编译器都能够识别do{…}while(0)这种无用的循环并进行优化,所以使用这种方法也不会导致程序的性能降低。
do...while(0)消除goto语句。
通常,如果在一个函数中开始要分配一些资源,然后在中途执行过程中如果遇到错误则退出函数,当然,退出前先释放资源,我们的代码可能是这样:
bool Execute()
{
// 分配资源
int *p = new int;
bool bOk(true);
// 执行并进行错误处理
bOk = func1();
if(!bOk)
{
delete p;
p = NULL;
return false;
}
bOk = func2();
if(!bOk)
{
delete p;
p = NULL;
return false;
}
bOk = func3();
if(!bOk)
{
delete p;
p = NULL;
return false;
}
// ..........
// 执行成功,释放资源并返回
delete p;
p = NULL;
return true;
}
这里一个最大的问题就是代码的冗余,而且我每增加一个操作,就需要做相应的错误处理,非常不灵活。于是我们想到了goto:
bool Execute() {
// 分配资源
int *p = new int;
bool bOk(true);
// 执行并进行错误处理
bOk = func1();
if(!bOk) goto errorhandle;
bOk = func2();
if(!bOk) goto errorhandle;
bOk = func3();
if(!bOk) goto errorhandle;
// ..........
// 执行成功,释放资源并返回
delete p;
p = NULL;
return true;
errorhandle:
delete p;
p = NULL;
return false;
}
代码冗余是消除了,但是我们引入了C++中身份比较微妙的goto语句,虽然正确的使用goto可以大大提高程序的灵活性与简洁性,但太灵活的东西往往是很危险的,它会让我们的程序捉摸不定,那么怎么才能避免使用goto语句,又能消除代码冗余呢,请看do...while(0)循环:
bool Execute()
{
// 分配资源
int *p = new int;
bool bOk(true);
do
{
// 执行并进行错误处理
bOk = func1();
if(!bOk) break;
bOk = func2();
if(!bOk) break;
bOk = func3();
if(!bOk) break;
// ..........
}while(0);
// 释放资源
delete p;
p = NULL;
return bOk;
}
分享到:
相关推荐
如果你是一名C程序员,你肯定很熟悉宏,它们非常强大,如果正确使用可以让你的工作事半功倍。...在Linux内核和其它一些著名的C库中有许多使用do{…}while(0)的宏定义。这种宏的用途是什么?有什么好处? Google的Robert
`do...while`循环开始时,`factorial`乘以当前的`n`,然后`n`自减1,直到`n`变为1或0,循环结束。最后,程序打印出1到n的累乘之积。 `README.txt`文件通常包含项目或代码的说明,例如如何运行程序、代码的目的等。...
总结来说,`while`循环和`do-while`循环在C语言中都有其独特的用途。`while`适合那些需要在执行前就检查条件的情况,而`do-while`则确保循环体至少执行一次,适用于某些特定的逻辑需求。通过实例代码的学习,我们...
总结起来,这份资料详细介绍了`while`循环的各种用途,包括计数、读取输入、使用`do...while`语句和解决实际问题,如计算斐波那契序列。通过这些练习,学生可以加深对C++循环结构的理解,并能够熟练地在实际编程中...
`do...while`先执行一次循环体再检查条件,而`while...do`先检查条件再执行循环体。 20. **代码输出** 代码中`a++`和`++a`的使用导致了变量a的值在不同地方被修改,最终输出结果为:b=10,c=12,d=120。 21. **...
Java程序设计:实验三 JAVA基本语法二 ...通过本实验,我们可以掌握if...else、switch...case分支语句、for、while、do-while循环和break、continue跳转语句等基本语法,并了解它们在实际应用中的用途。
do-while循环与while循环类似,但有一个显著区别:do-while循环至少会执行一次循环体,因为它的条件检查是在循环体执行之后进行的。基本形式为`do 循环体语句; while (条件);`。 在for循环中,我们通常使用它来执行...
- **控制结构**: 支持`if-then`条件语句、`while-do`循环语句。 - **过程调用**: 支持过程定义和调用,但不支持参数传递。 #### 2. PL/0语言的文法规则 PL/0语言的文法规则清晰地定义了语言的结构和组成部分,如...
谢丽聪老师的C语言课程中,第6章详细讲解了循环控制,包括`goto`语句、`while`语句、`do-while`语句、`for`语句以及`break`和`continue`语句。 首先,我们来讨论`goto`语句。`goto`是一种无条件跳转语句,它可以将...
本章主要介绍了四种循环结构:for循环、while循环、do-while循环以及循环的嵌套,同时也提到了两种控制循环流程的语句:continue和break。 1. **for循环**: - for循环语句的一般形式是`for(初始化; 条件; 更新)`...
本教学设计方案旨在帮助学生深入理解并掌握循环结构,包括for、while和do-while循环,以及相关的控制语句如break和continue。 一、循环结构的核心概念 循环结构的实质是重复执行一组语句,通过控制循环条件来决定...
基本语句包括赋值语句、表达式语句、if语句、switch语句、goto语句、while语句、do...while语句、for语句、break语句、continue语句等。这些语句是构建C程序的基础,每个语句都有其特定的用途和使用场景。 赋值语句...
- 在`for`、`while`或`do...while`循环中,使用`break`可以立即终止循环。 - 在`switch`语句中,每个`case`后面通常跟一个`break`语句,防止代码继续执行下一个`case`。 - **示例**: ```java for (int i = 0; i...
当你在循环体内部遇到`break`语句时,程序会立即退出当前循环,执行下一条语句,这适用于`for`、`while`和`do-while`循环。让我们通过几个实例来理解其用法: 1. **在`for`循环中的应用**: ```java for (int i =...
本实验报告中,重点讲解了高级语言程序设计中的一些关键概念和技巧,特别是关于逻辑运算符、逻辑表达式、条件判断语句(if、switch)、循环结构(while、do-while、for)以及嵌套循环的使用。 1. **逻辑运算符和...
`do { 循环体 } while(条件)`,即使初始条件不满足,do-while循环也会至少执行一次。 除了这些基本的循环结构,还有如foreach循环(也称为增强for循环),主要用于遍历集合或数组,语法简洁,如`for(元素类型 变量 ...
9. `do...while`:这是一个循环结构,先执行循环体,然后检查条件,如果条件满足则继续循环,否则停止。 10. `enum`:`enum`用于定义枚举类型,枚举类型是一组命名的整数值,方便表示和操作一组相关的常量。 11. `...
- **用途**:构成`while`和`do...while`循环结构。 - **说明**:根据条件的真假决定是否重复执行循环体。 #### 三、C51编译器的扩展ANSIC关键字 除了标准C语言的关键字外,C51还引入了一些特殊的扩展关键字,以...
- **循环语句** (`while Cond do Stmt`) - **过程调用语句** (`call ident`) - **复合语句** (`begin Stmt {; Stmt} end`) - **空语句** (`ε`) 这些特性使得PL/0成为一个理想的编程教学工具,特别是对于学习编译...
- **用途**:`do...while`循环的一部分,先执行循环体,再判断条件。 14. **double** - **用途**:64位双精度浮点数类型。 15. **else** - **用途**:`if`语句的一部分,当条件为假时执行的代码块。 16. **...