CSC270: Miscellaneous C, Part 2

The `switch' statement

[King 5.3] Sometimes, we want to do many different things based upon the many possible values of an expression. The `switch' statement does this: switch (expr) { case value1: ... case value2: ... case value3: ... default: ... } 1. The `expr' is evaluated *once* and its value is compared with each of the case values (value1, value2, value3, ... above) in turn, starting from the top. 2. When the first value that matches the expression is found, the statments under that case (... above) are executed. 3. If no case value is found, the statements after `default' are executed. The `default' case doesn't have to be present. The statements (... above) almost always end with a `break' statement: switch ( transactionType ) { case 1: printf( "Deposit\n" ); break; case 2: printf( "Withdrawl\n" ); break; case 3: printf( "Transfer\n" ); break; case 4: printf( "Bill payment\n" ); break; default: printf( "Unrecognized transaction type: %d\n", transactionType ); } If the `break' is left out, the program will continue executing the statements in the rest of the switch. For example, if all the `break's were left out of the code and the transactionType was 3, the output would be switch ( transactionType ) { case 1: printf( "Deposit\n" ); case 2: printf( "Withdrawl\n" ); case 3: printf( "Transfer\n" ); case 4: printf( "Bill payment\n" ); default: printf( "Unrecognized transaction type: %d\n", transactionType ); } --> Transfer Bill payment Unrecognized transaction type: 3

Typedefs

[King 7.6] You can define new types: typedef <type> <new type name> For example, to create a Boolean type, which is really a one-byte integer that takes on values 0 and 1: typedef unsigned char Boolean; \___________/ \_____/ | | type new name #define TRUE 1 #define FALSE 0 main() { Boolean x, y, z; x = TRUE; y = FALSE; z = x | y; printf( "x = %d, y = %d, z = %d\n", (int) x, (int) y, (int) z ); } The typedef is useful with arrays: typedef char FixedString[100]; `FixedString' is an array of 100 characters. main { FixedString str; str[0] = 'x'; str[1] = 'y'; str[2] = 'z'; str[3] = '\0'; printf( "string is %s\n", str ); }

Structs

[ King 16.1, 16.2, 16.3 ] An array is a collection of elements which are - all of the same type - referred to by an index A `structure' is a collection of elements which are - of possibly different types - referred to by a name A structure usually stores a collection of related items. A poor implementation of a string would store an array of characters and a length: struct { int length; char str[100]; } string1, string2; This statement defines two variables, `string1' and `string2'. Each variable contains two components called `length' and `str'. To refer to the components, we use the dot notation. In general, the form is variableName.fieldName Each component of the structure is called a `field'. For example, to initialize the strings (which don't have a terminating '\0' character, since the length field gives this information): string1.length = 2; string1.str[0] = 'x'; string1.str[1] = 'y'; for (i=0; i < NUM_BLANKS; i++) string2.str[i] = ' '; string2.length = NUM_BLANKS;

Arrays of structs

Note that an array can be a component of a structure. Similarly, we can have an array of structures: struct { int index; int numAdjNodes; int adjNodes[100]; } nodes[20]; This defines an array of 20 nodes, where each node is a structure with three fields: index, numAdjNodes, and adjNodes. This structure could store a node in a graph and the indices of adjacent nodes (`adj' stands for `adjacent'). In the code below, every node is made adjacent to node 0: for (i=0; i < 20; i++) { nodes[i].index = i; nodes[i].numAdjNodes = 1; nodes[i].adjNodes[0] = 0; }

Making your own structure types

It's tedious to type the whole structure definition every time you want to declare a new variable. C allows you to avoid this by defining a new type that is a structure: typedef struct { int index; int numAdjNodes; int adjNodes[100]; } NODE; This is a definition of a TYPE called `NODE'. It is NOT a declaration of a variable called `NODE'. Typically, people use uppercase letters or a Capitalized Word for their own type names. It helps when reading the program. After defining a new type, you can use it wherever you want: NODE a, b, c; NODE nodes[20]; These statements declare three variables -- a, b, and c -- of the NODE type, along with an array of 20 nodes. Much cleaner code is produced if you make the appropriate typedefs like this. Such variables are used in the normal way: a.index = 0; a.numAdjNodes = 0; nodes[5].index = 5; nodes[5].numAdjNodes = 1; nodes[5].adjNodes[0] = 1;