Test loops at the top or bottom? (while vs. do whi

2020-02-16 03:12发布

When I was taking CS in college (mid 80's), one of the ideas that was constantly repeated was to always write loops which test at the top (while...) rather than at the bottom (do ... while) of the loop. These notions were often backed up with references to studies which showed that loops which tested at the top were statistically much more likely to be correct than their bottom-testing counterparts.

As a result, I almost always write loops which test at the top. I don't do it if it introduces extra complexity in the code, but that case seems rare. I notice that some programmers tend to almost exclusively write loops that test at the bottom. When I see constructs like:

if (condition)
{
    do
    {
       ...
    } while (same condition);
}

or the inverse (if inside the while), it makes me wonder if they actually wrote it that way or if they added the if statement when they realized the loop didn't handle the null case.

I've done some googling, but haven't been able to find any literature on this subject. How do you guys (and gals) write your loops?

30条回答
成全新的幸福
2楼-- · 2020-02-16 03:46

Does avoiding do/while really help make my code more readable?

No.

If it makes more sense to use a do/while loop, then do so. If you need to execute the body of a loop once before testing the condition, then a do/while loop is probably the most straightforward implementation.

查看更多
别忘想泡老子
3楼-- · 2020-02-16 03:48

Here is the translation:

do { y; } while(x); 

Same as

{ y; } while(x) { y; }

Note the extra set of braces are for the case you have variable definitions in y. The scope of those must be kept local like in the do-loop case. So, a do-while loop just executes its body at least once. Apart from that, the two loops are identical. So if we apply this rule to your code

do {
    // do something
} while (condition is true);

The corresponding while loop for your do-loop looks like

{
    // do something
}
while (condition is true) {
    // do something
}

Yes, you see the corresponding while for your do loop differs from your while :)

查看更多
Luminary・发光体
4楼-- · 2020-02-16 03:48

It's actually meant for a different things. In C, you can use do - while construct to achieve both scenario (runs at least once and runs while true). But PASCAL has repeat - until and while for each scenario, and if I remember correctly, ADA has another construct that lets you quit in the middle, but of course that's not what you're asking. My answer to your question : I like my loop with testing on top.

查看更多
beautiful°
5楼-- · 2020-02-16 03:48

To write code that is correct, one basically needs to perform a mental, perhaps informal proof of correctness.

To prove a loop correct, the standard way is to choose a loop invariant, and an induction proof. But skip the complicated words: what you do, informally, is figure out something that is true of each iteration of the loop, and that when the loop is done, what you wanted accomplished is now true. The loop invariant is false at the end, for the loop to terminate.

If the loop conditions map fairly easily to the invariant, and the invariant is at the top of the loop, and one infers that the invariant is true at the next iteration of the loop by working through the code of the loop, then it is easy to figure out that the loop is correct.

However, if the invariant is at the bottom of the loop, then unless you have an assertion just prior to the loop (a good practice) then it becomes more difficult because you have to essentially infer what that invariant should be, and that any code that ran before the loop makes the loop invariant true (since there is no loop precondition, code will execute in the loop). It just becomes that more difficult to prove correct, even if it is an informal in-your-head proof.

查看更多
祖国的老花朵
6楼-- · 2020-02-16 03:49

I always follow the rule that if it should run zero or more times, test at the beginning, if it must run once or more, test at the end. I do not see any logical reason to use the code you listed in your example. It only adds complexity.

查看更多
闹够了就滚
7楼-- · 2020-02-16 03:50

The while loop will check "condition" first; if it's false, it will never "do something." But the do...while loop will "do something" first, then check "condition".

查看更多
登录 后发表回答