The While Loop
After the standard C
for
loop and the Objective-C 2.0
for...in
loop, the while
loop is the most common. Unlike the
full-featured for
loop and the specialized
for...in
loop, the while
is simpler and more
free-form.
The while
loop starts with the keyword while
followed by parentheses containing the condition. After the
parentheses, a single statement or block makes up the
body of the loop.
/* while loop with a single statement */
while (condition) statement;
/* while loop with a block */
while (condition)
{
block;
}
Watch out for a hard to spot bug when the while
loop is
followed by an empty statement created by an extra semicolon:
while (condition); /* <-- warning! empty statement! */
{
/* this block is not part of the loop */
/* it's always executed exactly once */
}
The condition in a while
loop is evaluated before
the body of the loop is executed, so you can create loops that execute
zero or more times. If you want the body of the loop to execute one or
more times, you can use a do...while
loop instead.
The initialization of the loop counter or other loop variables must be
done before the while
loop statement; often this means
declaring and initializing a local variable:
int i = 0;
while (i < 10)
When using a loop counter, it is important to remember to advance the
counter to the next value in the body of the loop. For instance, to
log the numbers 0 through 9:
int i = 0;
while (i < 10) {
NSLog(@"%d", i);
i++; /* advance the loop counter */
}
If you forget to advance the loop counter, you will create an infinite
loop.
int i = 0;
/* warning, infinite loop, i is always 0 */
while (i < 10) {
NSLog(@"%d", i);
/* oops, forgot to increment i */
}
The while
loop is frequently used when iterating over a
stream or sequence of unknown size where a loop counter is unnecessary.
For instance, to iterate over a null-terminated string by incrementing
the string pointer:
char const *s = "foobar";
while (*s) { /* while current character isn't zero */
NSLog(@"%c", *s); /* log the current character */
s++; /* increment address in s to next character */
}
Similarly, the idiomatic way to read characters from a standard C
FILE
is:
FILE *file = /* open file for reading ... */;
int ch;
while ( (ch = fgetc(file)) != EOF) {
NSLog(@"%c", ch);
}
The loop condition ( (ch = fgetc(file)) != EOF)
in this
idiom does three things:
-
fgetc(file)
gets the current character and advances to
the next
-
(ch = fgetc(file))
assigns the current character to
ch
-
(ch = ...) != EOF
checks that the value of
ch
is not EOF
Next time, we
will look at the do...while
loop.