tags:

views:

407

answers:

5

i have a code that does something like this:

while (doorIsLocked()) {
  knockOnDoor();
}
openDoor();

but i want to be polite and always knock on the door before i open it.

i can write something like this:

knockOnDoor();
while (doorIsLocked()) {
  knockOnDoor();
}
openDoor();

but i'm just wondering if there's a better idiom that doesn't repeat a statement.

thanks.

+41  A: 

You can use a do-while instead of a while-do loop:

do {

  knockOnDoor();

} while (doorIsLocked());

openDoor();

Unlike a while-do loop, the do-while executes the body once before checking the termination condition.

See also


Pre-test and post-test loops

The do-while loop -- sometimes called just a do statement -- in C/C++/C#/Java/some others is what is known as a "post-test" loop: the terminating condition is checked after each iteration. It loops while a condition is true, terminating immediately once it's false.

Pascal has a repeat-until loop, which is also a "post-test" loop; it loops while a condition is false, terminating immediately once it's true.

Fortran's do-while loop on the other hand is a "pre-test" loop: the terminating condition is checked before each iteration. In C/C++/Java/C#/some others, while-do and for loops are also "pre-test" loops.

Always check language reference when in doubt.

References

Related questions

polygenelubricants
+1  A: 

You could do a recursive call:

void openLockedDoor(){
    knockOnDoor();
    if( doorIsLocked() ){
        return openLockedDoor();
    }
    return openDoor();
}

but the do-while above works just as well (or even better depending on your compiler.)

wheaties
to me this recursive version seems to be way to expensive
niklasfi
@niklasfi Agreed. Some algorithms are best expressed recursively, but an iterative implementation is nearly always faster. There's no reason to worry about this unless performance is actually an issue, but likewise there's no reason to make an iterative algorithm into a recursive one for no good reason.
Tyler McHenry
people keep saying things liek that ... go an compile it and test it ... most modern compilers will replace this recursion with a loop now. The compiler is a lot cleverer than you. As such the actual compiled asembly is a long way fromt he code you write meanign that you have more expressive freedom than you think.
John Nicholas
@niklasfi How is it more expensive. As John has pointed out a modern compiler will optimize this to potentially the same code as a `do-while`.
wheaties
+3  A: 

@polygenelubricants already posted the obvious best solution to this.

In some cases though, it may be simpler to remove the condition from the loop entirely, and do something like this:

for (;;) {
  knockOnDoor();
  if (!doorIsLocked()) { break; }
}

since it gives you full control over what to do before and after the loop condition.

But when a do-while does what you need, definitely prefer that.

jalf
Why not replace the `for` with `while(true)` then?
fastcodejava
@fastcodejava: You can if you want to, but I prefer `for(;;)` for infinite loops. `for(;;)` says explicitly that there *is* no end condition, it should just keep looping. A `while(true)` specifies a condition -- admittedly, that condition isn't going to evaluate to `false` any time soon, but in my mind, an infinite loop is defined by *not having* a condition in the first place. That, and `while(true)` yields a warning on some compilers. ;)
jalf
A: 

You forgot to Wait...If you keep on knocking it would also be impolite...so best way is to do it like this:

#define WAITING_TIME 2000 //2 Seconds are enough waiting time for another knock
while(doorIsLocked()){
knockOnDoor();
//Now wait
Sleep(WAITING_TIME);
}
openDoor();
Orochi
Depends on how long it takes to check wether the door is locked... ;) This would have better been a comment though.
Georg Fritzsche
:) yeh... you are right...but i thought as no body mentioned it and the person asking is keen on morals so...i shared my thoughts :)
Orochi
+4  A: 

Here you are:

while(knockOnDoor(),doorIsLocked());
Luther Blissett
comma operator abuse. Love it but it's less readable.
wheaties