首页 > 代码可读性: 避免do/while 循环

代码可读性: 避免do/while 循环

在看<< the art of readable code >>, 作者提到要 避免do/while循环:

What’s weird about a do/while loop is that a block of code may or may not be reexecuted based on a condition underneath it. Typically, logical conditions are above the code they guard—this is the way it works with if, while, and for statements. Because you typically read code from top to bottom, this makes do/while a bit unnatural. Many readers end up reading the code twice.

但do/while有时候也很适用一些场景, 比如前两天 我在一个问题里回答:

do{
    result = msgrcv(id, (void *) &msg, sizeof(msg.text),
         msgtyp, MSG_NOERROR);
} while(result == -1 && errno == EINTR);

我们至少需要做一次msgrcv, 然后判断出错情况 是否需要循环. 这里do/while 就非常适合. 问问大家的看法.


其实就像你引用的那段话说的, do/while 结构把条件放到了代码的后面,这种做法是反人类的,会导致读者看到条件的时候又回过头来重新看一遍代码;所以不要优先考虑 do/while 结构,只有当使用 do/while 能够显著改善可读性的时候才考虑它。

你举的例子中,do/while 块中的代码只有两行,这时即使把循环条件放到最后面(第三行), 也不会对读代码的人造成太大的影响,所以在这个例子中用 do/while 是比较合适的。而如果其中的代码有十行,恐怕就要斟酌一下要不要用了。


存在即合理,虽然一般情况下用到 do/while 循环的时候很少,但有时候用用也无妨。

其实 do/while 完全可以由 while/do 来代替,当然得配合定义 function 才会比较简捷,比如

// No.1
do {
    c = func();
} while (c);

可以换成

// No.2
c = func();
while (c) {
    c = func();
}

然后被一些懒牛改写成

// No.3
while (func()) {}

相比之下 No.2 烦琐,No.3 晦涩,还是 No.1 好懂些。

当然也有人会写成

do {} while (func());

一样晦涩,还多写几个字。

如果说 do {... } 中的语句比较多的情况……还是老办法,封装成 function 就能解决,一目了然。要是觉得不清楚函数在干啥,还可以在语句块里写句注释。

当然,也有人不喜欢用 while 循环的,所以就用 for 循环解决了

for (c = func(); c; c = func()) {}

或者更 ZUO 的

for (;;) {
    if (func()) {
        break;
    }
}

当然,while/do 或者 do/while 也可以写成死循环由条件判断 break 这种形式。

总的来说,语法提供了,逻辑没得错误,自己写着舒服,大家都看得懂——那就用呗!

【热门文章】
【热门文章】