C/C++中的do-while循环的妙用

本文探讨了do-while循环的独特用途,包括如何利用其必定执行一次的特点进行代码块的封装,以及如何作为代码块的入口和出口。此外,还讨论了这种方式相较于if-else和goto语句的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在公司实习,看后台服务器的代码比较多,见识了很多东西的妙用,比如说do-while循环的用法。

关于do-whilewhilefor的区别我就不多说了,其中要明确的一点是do-while循环是一定会执行一遍循环体

利用do-while循环是一定会执行一遍循环体的这个特点,可以完成两个功能:封装代码块、提供代码块入出口。下面细细来说。

封装代码块

这个东西主要体现在宏定义中,如果你经常看Linux内核就会发现类似下面的用法:

#define SWAP(a, b)      \
    do {                \
        int tmp = (a);  \
        (a) = (b);      \
        (b) = tmp;      \
    } while(0)

这个里面的\是表示下一行和当前行属于同一个部分,最后一条语句不要加;,因为调用的时候SWAP(a, b);里面的;会加在最后一条语句上。这就相当于用宏完成了一个函数,如果不用do_while循环把这三行语句封装成一个代码块的话会出现很多问题。即

#define SWAP(a, b)      \
        int tmp = (a);  \
        (a) = (b);      \
        (b) = tmp

首先,如果这个SWAP用到一个没有加{}for循环中,就会出现问题,你可以试着展开下:

for (int i = 0; i < n; i++)
    // SWAP(a, b);
    int tmp = (a);
    (a) = (b);
    (b) = tmp;

这段代码只有int tmp = (a);执行了n次,故不对。用do-while循环包裹就不会出现这中问题。

其次,如果用do-while在宏中封转代码块还可以解决定义变量时的重命名问题、作用域问题。如果不用do-while循环,在宏中定义的变量的作用域就是宏调用时所处的代码块,故这个时候如果该代码块之前定义了tmp这个变量,那么就会出现重定义问题;而如果用了do-whiledo-while中自成一块域,故在宏中定义的变量,在do-while循环跳出时就超出作用域了,所以可以放心地在宏中定义变量。

for (int i = 0; i < n; i++) {
    int tmp = 5;
    // SWAP(a, b);

    // do                   
        int tmp = (a);  
        (a) = (b);
        (b) = tmp;
    // while (0);
}

提供代码块入出口

先来个代码,看看不用do-while循环的样子。

void work1()
{
    gg();

    // start
    if (condition1) {
        deal1;
    } else if (condition2) {
        deal2;
    } else if (condition3) {
        deal3;
    }
    // end

    gg();
    aa();
}

这个代码中要通过3个互斥的判断条件才能执行下一步,里面使用了多了if - else使得代码不那么直观。因此,我们可以通过goto语句来解决这个问题。

void work2()
{
    gg();

    // start
    if (condition1) {
        deal1;
        goto OUT;
    if (condition2) {
        deal2;
        goto OUT;
    if (condition3) {
        deal3;
        goto OUT;
    }
    // end

OUT:
    gg();
    aa();
}

现在就清晰多了,不过使用了很多的goto语句,这是不提倡的,因此,现在用do-while来封装一下。

void work3()
{
    gg();

    // start
    do {
        if (condition1) {
            deal1;
            break;
        if (condition2) {
            deal2;
            break;
        if (condition3) {
            deal3;
            break;
        }
    while (0);
    // end

    gg();
    aa();
}

这个才是最清晰的写法,用break跳出代码块代替goto,且3个条件判断语句还有缩进。

正是break提供了代码块的出口(出口在while (0);的后一条语句),这也是breakdo-while的一个局限吧,因为代码块的出口是固定的,而goto提供的出口是任意的。

do-while去掉了很多的if-elsegoto语句。

总结

do-while第一个功能是很明显的,也是很有道理的,第二个功能可能是仁者见仁智者见智了,我是觉得do-whileif-elsegoto更直观。这只是编程的技巧,选择你喜欢的技巧去用吧。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值