Goto
Last time we looked at
using the continue
statement to skip to the next iteration
of a loop. This week, we will finish looking at loops with the most
primitive looping statement of all: the goto
statement.
A goto
statement always references a label, which
is simply an identifier followed by a colon (:). When the
goto
statement is reached, execution jumps to the label
and continues from that point. The label can be before or after the
goto
statement.
// goto and label examples
start: // label named "start"
// do some stuff
if (...) {
goto start;
}
// do more stuff
if (...) {
goto end;
}
// and more stuff
end: // label named "end"
Labels do nothing by themselves except mark places in code that you can
jump to using goto
.
The goto
statement has one big limitation: it only works
within a single function. If you write something like this:
// goto may only jump to labels within a function
// THIS CODE DOESN'T COMPILE
void function1(void) {
label1:
goto label2;
}
void function2(void) {
label2:
goto label1;
}
The compiler will produce error messages like label ‘label1’ used
but not defined. Without this restriction, goto
could be abused to create difficult to understand spaghetti code (ask
any old time BASIC programmer about this). Because of this
restriction, label names are local to the function that contains them,
so you can use the same label name in different functions.
Though mostly eschewed in favor of the
for
,
for...in
,
while
and
do...while
loops, the goto
can be used to implement loops:
int i = 0;
startLoop: // label "startLoop"
NSLog(@"%d", i);
i++;
if (i < 10) {
goto startLoop;
}
This loop logs the numbers from 0 to 9. It's equivalent to this while
loop:
int i = 0;
while (i < 10) {
NSLog(@"%d", i);
i++;
}
Because the other looping statements are more compact and expressive,
you will rarely see goto
used to build loops.
Next time,
we'll look at common uses for goto
.