Objects First |
if (x==val1) { .. } else if (x==val2) { .. }
else if (x==val3) ...
While such a statement if perfectly OK and if formatted sensibly:
if (x==val1) {
.. }
else if (x==val2) {
.. }
else if (x==val3) {
.. }
else { /* Don't forget to catch unintended errors here! */
printf("Illegal value for x: %d\n", x);
}
quite easy to read, C provides us with a short-hand notation in the form
of a switch statement.
switch( x ) {
case val1:
....
break;
case val2:
....
break;
case val3:
....
break;
default:
printf("Illegal value for x: %d\n", x);
}
Note carefully the break statements!
C switch
cases fall through to the next case
if the break is not there.
This is a particular trap for those used to other languages, such
as Pascal, where branches of a case statement do not fall through to
the next case. Although a trap for new C programmers, the fall-through property
of switch statements may be used in some convenient ways.
Consider a system
where the user types in single letter commands to the machine - but we don't
want to force him or her to ensure that the commands are in upper or lower case,
ie if 'A' signifies the 'Add' command, then
'a' should do just as well:
char user_response;
int valid_response;
do {
user_response = read_user_input("Enter next command");
valid_response = TRUE;
switch ( user_response ) {
case 'a':
case 'A':
process_add_command();
break;
case 'd':
case 'D':
process_delete_command();
break;
default:
printf("%c is not valid, enter A or D\n",
user_response );
valid_response = FALSE;
}
while( !valid_response );
We can also see that the controlling expression in a
switch statement can be
a character as well as an enumerated type.
In fact, the formal requirement is an
integral expression - any expression that evaluates to an integer.
Thus
enum's and
char's can be used
because they are promoted to
int
when used in expressions.
Of course, we can use integers directly:
int n = ...;
switch( n ) {
case 0 : printf("zero"); break;
case 1 : printf("one"); break;
case 2 : printf("two"); break;
default: printf("many");
}
Note that although this example is acceptable,
many switch statements using
integer values in the case .. parts would fail
the NO MAGIC NUMBERS rule (and earn you a certain failure in the practical programming
test!). For example, if a bank's system assigns numeric codes to transactions:
int trans_code = ...;
switch( trans_code ) {
case 11 : withdraw(); break;
case 23 : deposit(); break;
case 13 : balance(); break;
default: printf("illegal transaction type");
}
is definitely unacceptable. It should be re-coded as:
/* TransactionType.h - TransactionType class */
typedef enum { withdraw_trans = 11,
deposit_trans = 23,
balance_req = 13 } TransactionType;
#include "TransactionType.h"
TransactionType trans_code = ...;
...
switch( trans_code ) {
case withdraw_trans : withdraw(); break;
case deposit_trans : deposit(); break;
case balance_req : balance(); break;
default: printf("illegal transaction type");
}
or possibly the equivalent using #define statements
to hide the actual transaction type encodings.
char *ColourString( Colour c ) {
switch( c ) {
case black : return "black";
case blue : return "blue";
case red : return "red";
case yellow : return "yellow";
default : return "unknown colour";
}
}
Note that this function return a
char * - or pointer to
a character. For more about pointers,
refer to later sections of this book.
For the moment, note that you can use this function anywhere
that you need a string.
In particular, you can use it in printf:
Colour c;
c = RectColour( r );
printf("Colour is %s\n", ColourString( c ) );
Key terms |
|
Continue on to Strings and Pointers Back to the Table of Contents |