Author : Brian Kernighan
Page : << Previous 8 Next >>
break;
}
The case statements label the various actions we want;
default gets done if none of the other cases are satisfied.
(A default is optional; if it isn't there, and none of the
cases match, you just fall out the bottom.)
The break statement in this example is new. It is
there because the cases are just labels, and after you do
one of them, you fall through to the next unless you take
some explicit action to escape. This is a mixed blessing.
On the positive side, you can have multiple cases on a sin-
gle statement; we might want to allow both upper and lower
case 'a': case 'A': ...
case 'b': case 'B': ... etc.
But what if we just want to get out after doing case `a' ?
We could get out of a case of the switch with a label and a
goto, but this is really ugly. The break statement lets us
exit without either goto or label.
switch( c ) {
case 'a':
aflag++;
break;
case 'b':
bflag++;
break;
...
}
/* the break statements get us here directly */
The break statement also works in for and while statements _
it causes an immediate exit from the loop.
The continue statement works _o_n_l_y inside for's and
while's; it causes the next iteration of the loop to be
started. This means it goes to the increment part of the
for and the test part of the while. We could have used a
continue in our example to get on with the next iteration of
the for, but it seems clearer to use break instead.
The main use of structures is to lump together collec-
tions of disparate variable types, so they can conveniently
be treated as a unit. For example, if we were writing a
compiler or assembler, we might need for each identifier
information like its name (a character array), its source
line number (an integer), some type information (a charac-
ter, perhaps), and probably a usage count (another integer).
char id[10];
int line;
char type;
int usage;
We can make a structure out of this quite easily. We
first tell C what the structure will look like, that is,
what kinds of things it contains; after that we can actually
reserve storage for it, either in the same statement or
separately. The simplest thing is to define it and allocate
storage all at once:
struct {
char id[10];
int line;
char type;
int usage;
} sym;
This defines sym to be a structure with the specified
shape; id, line, type and usage are members of the struc-
ture. The way we refer to any particular member of the
structure is
structure-name . member
as in
sym.type = 077;
if( sym.usage == 0 ) ...
while( sym.id[j++] ) ...
etc.
Although the names of structure members never stand alone,
they still have to be unique _ there can't be another id or
usage in some other structure.
So far we haven't gained much. The advantages of
structures start to come when we have arrays of structures,
or when we want to pass complicated data layouts between
functions. Suppose we wanted to make a symbol table for up
to 100 identifiers. We could extend our definitions like
char id[100][10];
int line[100];
char type[100];
int usage[100];
but a structure lets us rearrange this spread-out informa-
tion so all the data about a single identifer is collected
into one lump:
struct {
char id[10];
int line;
char type;
int usage;
} sym[100];
This makes sym an array of structures; each array element
has the specified shape. Now we can refer to members as
sym[i].usage++; /* increment usage of i-th identifier */
for( j=0; sym[i].id[j++] != '\0'; ) ...
etc.
Thus to print a list of all identifiers that haven't been
used, together with their line number,
for( i=0; i<nsym; i++ )
if( sym[i].usage == 0 )
printf("%d\t%s\n", sym[i].line, sym[i].id);
Suppose we now want to write a function lookup(name)
which will tell us if name already exists in sym, by giving
its index, or that it doesn't, by returning a -1. We can't
pass a structure to a function directly _ we have to either
define it externally, or pass a pointer to it. Let's try
the first way first.
int nsym 0; /* current length of symbol table */
struct {
char id[10];
int line;
char type;
int usage;
} sym[100]; /* symbol table */
main( ) {
Page : << Previous 8 Next >>