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条回答
小情绪 Triste *
2楼-- · 2020-02-16 03:52

The first tests the condition before performing so it's possible your code won't ever enter the code underneath. The second will perform the code within before testing the condition.

查看更多
干净又极端
3楼-- · 2020-02-16 03:52

Both conventions are correct if you know how to write the code correctly :)

Usually the use of second convention ( do {} while() ) is meant to avoid have a duplicated statement outside the loop. Consider the following (over simplified) example:

a++;
while (a < n) {
  a++;
}

can be written more concisely using

do {
  a++;
} while (a < n)

Of course, this particular example can be written in an even more concise way as (assuming C syntax)

while (++a < n) {}

But I think you can see the point here.

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

For anyone who can't think of a reason to have a one-or-more times loop:

try {
    someOperation();
} catch (Exception e) {
    do {
        if (e instanceof ExceptionIHandleInAWierdWay) {
            HandleWierdException((ExceptionIHandleInAWierdWay)e);
        }
    } while ((e = e.getInnerException())!= null);
}

The same could be used for any sort of hierarchical structure.

in class Node:

public Node findSelfOrParentWithText(string text) {
    Node node = this;
    do {
        if(node.containsText(text)) {
            break;
        }
    } while((node = node.getParent()) != null);
    return node;
}
查看更多
ら.Afraid
5楼-- · 2020-02-16 03:55

I would say it is bad practice to write if..do..while loops, for the simple reason that this increases the size of the code and causes code duplications. Code duplications are error prone and should be avoided, as any change to one part must be performed on the duplicate as well, which isn't always the case. Also, bigger code means a harder time on the cpu cache. Finally, it handles null cases, and solves head aches.

Only when the first loop is fundamentally different should one use do..while, say, if the code that makes you pass the loop condition (like initialization) is performed in the loop. Otherwise, if it certain that loop will never fall on the first iteration, then yes, a do..while is appropriate.

查看更多
Bombasti
6楼-- · 2020-02-16 03:56

As noted by Piemasons, the difference is whether the loop executes once before doing the test, or if the test is done first so that the body of the loop might never execute.

The key question is which makes sense for your application.

To take two simple examples:

  1. Say you're looping through the elements of an array. If the array has no elements, you don't want to process number one of zero. So you should use WHILE.

  2. You want to display a message, accept a response, and if the response is invalid, ask again until you get a valid response. So you always want to ask once. You can't test if the response is valid until you get a response, so you have to go through the body of the loop once before you can test the condition. You should use DO/WHILE.

查看更多
疯言疯语
7楼-- · 2020-02-16 03:57

I write mine pretty much exclusively testing at the top. It's less code, so for me at least, it's less potential to screw something up (e.g., copy-pasting the condition makes two places you always have to update it)

查看更多
登录 后发表回答