do{}while(0)用法

do{}while(0)大致有两种基本用法:

 

1. 宏定义

    当宏定义中有多个语句时,采用do{}while(0)可以避免不必要的错误。

    我们从一般的宏定义引出使用do{}while(0)的好处

    1.1 原始定义

   #define return_if_failed(p)  if (p) { /

                                                           printf(#p“ failed!/n”); /

                                                           return; /

                                                      }

     该宏在使用if else语句时出现问题

     例如:1> if (str)

              2>    return_if_failed(p);

              3> else

              4>   ...

     分析:首先会出现编译错误,因为第2>行后的";"实际上是代表空语句,也间接表明了if语句的结束,所以后面的else会出现编译错误。

              去掉该";"后,就不会有编译错误,但是出现语义错误。第3>行的else本来和第1>的if搭配,但是宏替换后和宏中的if搭配了。

 

     1.2 改进定义一——加入{}

     #define return_if_failed(p)  { /

                                                 if (p) { /

                                                           printf(#p“ failed!/n”); /

                                                           return; /

                                                         }  /

                                               }

    这样定义可以消除语义错误,但是还是无法消除语法错误,除非按照下面的写法:

    例如:1> if (str)

              2>    return_if_failed(p) // 即去掉最后的";"

              3> else

              4>   ...

    分析:这显然不符合编程习惯

 

    1.3 改进定义一——通用宏定义,使用do{}while(0)

    #define return_if_failed(p) do{ if (p) { printf(#p“ failed!/n”); return;}}while(0)

    // 注意whlie(0)后没有";"

    分析:这样既没有语法错误,也不会产生语义错误。

    当然如果按照下面方法使用宏,则1.1 1.2 1.3都不会产生错误(语法,语义)

 

     例如:1> if (str)  {

              2>    return_if_failed(p);

              3>} else {

              4>   ...

              5>}

 

     诚然,这是一个好的,应该提倡的编程习惯,但一般这样的宏都是作为library的一部分出现的,而对于一个library的作者,他所要做的就是让其库具有通用性,强壮性,因此他不能有任何对库的使用者的假设,如其编码规范,技术水平等。(该句为一位网上老兄的话,很有道理)

   2. 消除代码冗余

     经常会遇到这样的程序:

     if (a) {

       ...

 

       return false;

    } else if (b) {

       ...

 

       return false;

 

    } else if (c) {

       ...

 

 

 

       return false;

 

 

    } else if (d) {

       ...

 

 

 

       return false;

 

 

    } else if (d) {

       ...

 

 

 

       return false;

    }

    很多的return false;

 

    使用do{}while(0)就变的很简单了

    do {

     if (a) {

       ...

 

       break;

    } else if (b) {

       ...

       break;

 

    } else if (c) {

       ...

       break;

 

    } else if (d) {

       ...

 

 

       break;

 

    } else if (e) {

       ...

 

 

 

 

       break;

    }

  } while (0);

    free(p);

    p = NULL;

    return false;

   当然也可以用goto语句来实现

 

       free(p);

       p = NULL;

       free(p);

       p = NULL;

       free(p);

       p = NULL;

       free(p);

       p = NULL;

       free(p);

       p = NULL;

 

<think> 我们正在讨论C++中的do-while循环。do-while循环是一种后测试循环,即循环体至少执行一次,然后在循环体的末尾测试条件。如果条件为真,则再次执行循环体,否则退出循环。 ### do-while循环的基本语法 ```cpp do { // 循环体:需要重复执行的代码 } while (condition); // 注意分号 ``` ### 代码示例 以下是一个简单的示例,使用do-while循环让用户输入一个正整数,直到输入有效为止: ```cpp #include <iostream> using namespace std; int main() { int num; do { cout << "请输入一个正整数: "; cin >> num; if (num <= 0) { cout << "输入无效,请重新输入!" << endl; } } while (num <= 0); // 当输入的数小于等于0时,继续循环 cout << "您输入的正整数是: " << num << endl; return 0; } ``` ### 代码解释 1. **循环体**:程序首先执行循环体内的代码,提示用户输入一个整数,然后读取输入。 2. **条件检查**:在循环体的末尾,检查条件`num <= 0`。如果条件为真(即输入的数不是正整数),则继续循环,要求用户重新输入;否则,退出循环。 3. **至少执行一次**:即使第一次输入就满足条件(即输入的是正整数),循环体也已经执行了一次。 ### 与while循环的区别 - **while循环**:先测试条件,如果条件为假,则循环体一次都不执行。 - **do-while循环**:先执行循环体,再测试条件,因此循环体至少执行一次。 ### 使用场景 当你需要至少执行一次循环体时,使用do-while循环。例如: - 显示菜单并等待用户选择,直到选择退出。 - 读取用户输入,直到输入有效。 ### 另一个例子:菜单选择 ```cpp #include <iostream> using namespace std; int main() { char choice; do { cout << "菜单选项:" << endl; cout << "1. 选项一" << endl; cout << "2. 选项二" << endl; cout << "q. 退出" << endl; cout << "请选择: "; cin >> choice; switch(choice) { case '1': cout << "执行选项一..." << endl; break; case '2': cout << "执行选项二..." << endl; break; case 'q': cout << "退出程序..." << endl; break; default: cout << "无效选项,请重新选择!" << endl; } } while (choice != 'q'); // 当选择不是'q'时继续循环 return 0; } ``` ### 注意事项 1. 在do-while循环的条件后面必须有一个分号`;`。 2. 循环体内应有改变循环条件的语句,否则可能造成无限循环。 §§相关问题§§: 1. do-while循环和while循环在哪些场景下不能互换? 2. 在do-while循环中,如果条件一开始就为假,循环体执行几次? 3. 如何避免do-while循环中的无限循环? 4. 在C++中,do-while循环能否嵌套使用?请举例说明。 </think># C++中`do-while`循环的详细使用方法 `do-while`循环是C++中的一种后测试循环结构,它先执行循环体,然后再检查循环条件。这意味着循环体**至少会执行一次**,无论初始条件是否满足。 ## 基本语法 ```cpp do { // 循环体(需要重复执行的代码) } while (condition); // 注意分号 ``` ## 关键特性 1. **后测试**:先执行循环体,再检查条件 2. **至少执行一次**:无论初始条件如何,循环体至少执行一次 3. **条件为真时继续**:如果条件表达式结果为`true`,循环继续执行 ## 完整代码示例 ```cpp #include <iostream> using namespace std; int main() { int count = 0; // 基本do-while示例 cout << "基本do-while示例:" << endl; do { cout << "循环次数: " << count << endl; count++; } while (count < 5); cout << "\n------------------------\n"; // 输入验证示例 int number; do { cout << "请输入1到10之间的数字: "; cin >> number; if(cin.fail()) { cin.clear(); // 清除错误状态 cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 清空缓冲区 cout << "输入无效,请重新输入!" << endl; number = -1; // 设置无效值以继续循环 } else if(number < 1 || number > 10) { cout << "数字必须在1到10之间!" << endl; } } while(number < 1 || number > 10); cout << "您输入的有效数字是: " << number << endl; cout << "\n------------------------\n"; // 菜单系统示例 char choice; do { cout << "\n菜单选项:" << endl; cout << "1. 选项一" << endl; cout << "2. 选项二" << endl; cout << "3. 选项三" << endl; cout << "q. 退出" << endl; cout << "请选择: "; cin >> choice; switch(choice) { case '1': cout << "执行选项一..." << endl; break; case '2': cout << "执行选项二..." << endl; break; case '3': cout << "执行选项三..." << endl; break; case 'q': cout << "退出程序..." << endl; break; default: cout << "无效选择,请重试!" << endl; } } while(choice != 'q'); return 0; } ``` ## 代码解释 ### 1. 基本do-while示例 ```cpp int count = 0; do { cout << "循环次数: " << count << endl; count++; } while (count < 5); ``` - 循环从0开始,输出0到4 - 循环体至少执行一次(即使初始条件不满足) - 每次循环后检查`count < 5`条件 ### 2. 输入验证示例 ```cpp do { // 提示输入 // 检查输入是否有效 if(cin.fail()) { // 处理非数字输入 } else if(number < 1 || number > 10) { // 处理范围外数字 } } while(number < 1 || number > 10); ``` - 用户必须输入有效的1-10之间的数字才能退出循环 - `cin.fail()`检查输入失败(如输入字母) - `cin.clear()`清除错误状态 - `cin.ignore()`清空输入缓冲区 ### 3. 菜单系统示例 ```cpp do { // 显示菜单 // 获取用户选择 switch(choice) { // 处理不同选择 } } while(choice != 'q'); ``` - 典型的菜单系统结构 - 用户可以选择不同选项 - 输入'q'退出循环 - 无效选择会提示重新输入 ## 与`while`循环的对比 | 特性 | `do-while`循环 | `while`循环 | |------|----------------|-------------| | **执行顺序** | 先执行循环体,再检查条件 | 先检查条件,再执行循环体 | | **最少执行次数** | 至少执行一次 | 可能一次都不执行 | | **适用场景** | 输入验证、菜单系统 | 条件依赖循环体结果的情况 | | **语法** | 以分号结束 | 没有结束分号 | ## 最佳实践 1. **输入验证**:最适合需要至少获取一次用户输入的场景 2. **菜单系统**:构建交互式菜单的理想选择 3. **避免无限循环**:确保循环体内有改变循环条件的语句 4. **合理使用分号**:注意`do-while`循环以分号结束 5. **代码可读性**:对于复杂的循环体,使用注释明确循环目的
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值