Also check out this xkcd comic, which really demonstrates how dangerous the use of gotos can be. (Thanks to Midn Kursawe for pointing it out to me.)
Also, find (and tell me about) a typo, misspelling or grammar error in Dijkstra's article. Ha - now you have to read it!
int i = 1;
slp:
printf("%d\n",i);
++i;
if (i <= 10)
goto slp;
int i = 1,j;
while(i <= 10)
{
printf(",");
for(j = 0; j < i; ++j)
printf("x");
++i;
}
printf("\n");
This is really clear, but it doesn't really work, because it
sticks a comma before the first x. It's easy to fix this with
a goto:
int i = 1,j;
goto ac;
while(i <= 10)
{
printf(",");
ac:
for(j = 0; j < i; ++j)
printf("x");
++i;
}
printf("\n");
Now, there are other ways, of course. But this is nice
because it keeps the same structure as our original, and adds
no new tests to the code. In fact, the first "i <= 0" test
is even avoided.
int i, j;
for(i =0; i < 100; ++i)
for(j = i+1; j < 100; ++j)
if (fabs(sin(i) - sin(j)) >= 1.99) goto found;
found:
/* code for doing whatever you wanted i and j for! */
Once again, there are other ways to do this, but none of them
is as straightforward ... nor as efficient.
NOTE: Java offers "labeled break" statements, which are essentially like our use of gotos here, and labeled continue statements as well. You stick a label (just like C labels) in front of a loop, and "break foo;" breaks out of the loop labeled foo.
/******************************************************
* This is a horrible program that reads a line of text,
* expecting a number in binary. The text can only be
* ' '*(0|1)+' '*'\n' or it prints an error message. So
* "101" or " 101" or "101 " or " 101 " are all good.
* " " and "101k" are bad. If the input is good, the
* program prints the decimal value of the binary number.
******************************************************/
#include <stdio.h>
int main()
{
int x = 0;
char c;
goto rs;
fns:
if (c != '1' && c != '0') goto er;
goto ns;
rd:
c = getchar();
ns:
if (c == '1') { x = x*2 + 1; goto rd; }
if (c == '0') { x = x*2; goto rd; }
es:
if (c == ' ')
{
c = getchar();
goto es;
}
if (c == '\n') goto done;
er:
printf("Error!\n");
return 1;
rs:
c=getchar();
if (c == ' ') goto rs;
else goto fns;
done:
printf("%i\n",x);
return 0;
}
Admittedly, bad programs can be written without the aid of
gotos, so the fact that this is bad doesn't imply gotos are
bad. However, maybe the way in which this is bad
will be suggestive of the way that gotos can be hard
to understand.
int x;
scanf("%i",&x);
if (x > 0)
goto foo;
int y = -x;
foo:
printf("%i\n",y);
Lexical scoping rules say that y should be
visible in the printf statement, but what happens if the
x read in from the user is positive? Then we
jump over the definition and initialization of
y. How should that be handled?