3.8 Goto
The goto statement has a well-deserved reputation for being able to produce unreadable “spaghetti” code. It is almost never necessary to use one, and they should be avoided in general. However, on rare occasions they are convenient and safe. A goto statement provides the ability to jump to a named-label anywhere within the same function.
One situation where a goto can be useful is if it becomes necessary to break out of a deeply nested structure, such as nested loops. A break statement cannot do this as it can only break out of one level at a time. The following example gives the basic idea.
#include <stdio.h> /* for printf() */
#include <stdlib.h> /* for rand() */
#include <string.h> /* for memset() */
#define SIZE 1000
enum { VAL1=’a’, VAL2=’b’, VAL3=’Z’ };
int main(void) /* Demonstrate a legitimate use of goto (adapted from K&R page 66). This example is contrived, but the idea is to
* find a common element in two arrays. In the process, we demonstrate a couple of useful standard library functions. */
{
char a[SIZE], b[SIZE];
int i, j;
/* Initialise arrays so they are different from each other */
memset(a, VAL1, SIZE);
memset(b, VAL2, SIZE);
/* Set a random element in each array to VALUE */
a[rand()%SIZE] = VAL3;
b[rand()%SIZE] = VAL3;
/* Search for location of common elements */
for (i=0; i<SIZE; ++i)
for (j=0; j<SIZE; ++j)
if (a[i] == b[j])
goto found;
/* Error: match not found */
printf("Did not find any common elements!!\n");
return 0;
found: /* Results on success */
printf("a[%d] = %c and b[%d] = %c\n", i, a[i], j, b[j]);
}
The standard function memset() fills the first SIZE characters of array a with the value ’a’.
The standard function rand() returns a pseudo-random number from the range 0 to RAND_MAX, where RAND_MAX is an integer constant defined in header-file stdlib.h.
The named-label found: marks the next statement (the printf()) as the place to which goto will branch. A named-label must always be followed by a statement, even if it is just a null statement. For example,
found: ; /* label to jump to a null statement */
No comments:
Post a Comment