ECE-1021 

Selection Structures in C

(Last Mod: 27 November 2010 21:38:36 )

ECE-1021 Home



Objectives


Overview

The C programming language provides several selection structures to aid in structured programming. The if(), if()/else statements and the conditional operator perform a "1 of 2" path selection based on a logical test expression. The switch() statement performs a "1 of N" path selection based on the evaluation of an integer expression.

In each of the descriptions below, an example code fragment containing the structure being discussed will be presented. To illustrate how this structure appears in the context of the code around it, the structure is preceded by a code block called prior_code and followed by a code block called next_code. These blocks are not part of the structure. To emphasize this, the corresponding flowchart will have a dashed line surrounding just that portion of the chart which is part of the structure being discussed.

One thing to note is that, in each case, the dashed block represents a block of code that conforms to the single-entry/single-exit paradigm.


The if() Statement

The syntax of the if() statement is as follows:

prior_code;

 

if (test)

    if_code;

 

next_code;

After the prior_code block as finished, the test expression, which can be any expression that yields a value, is evaluated. If that value is identically equal to zero it is considered False and the if_code block is skipped. If it evaluates to any value other than zero, the if_code block is executed. In either case, the next_code block is then executed.

The if_code block consists of exactly one statement. But that one statement can be a null statement (which would be the case if a semicolon were accidentally placed after the closing parentheses of the test expression, a single statement, or a compound statement. An example of the latter case, which is extremely common, is shown below:

prior_code;

 

if (test)

{

    /* if_code block */

    statement_1;

    statement_2;

    ...

    statement_N;

}

 

next_code;

A very common mistake that people make is to write code as follows:

prior_code;

 

if (test)

    statement_1;

    statement_2;

 

next_code;

Visually, this looks like both statement_1 and statement_2 are controlled by the if() statement. They are not. The if() statement controls only the next statement - which in this case is just  statement_1. Regardless of the outcome of test, statement_2 will always execute. This code is perfectly legal and will compile without warnings - the compiler does not consider indentation when compiling code.

 


The if()/else Statement

The syntax of the if()/else statement is as follows:

prior_code;

 

if (test)

    if_code;

else

    else_code;

 

next_code;

After the prior_code block as finished, the test expression, which can be any expression that yields a value, is evaluated. If that value is identically equal to zero it is considered False and the if_code block is skipped but the else_code block is executed. If it evaluates to any value other than zero, the if_code block is executed but the else_code block is skipped. In short, this construct ensured that exactly one of the two blocks will be executed. In either case, the next_code block is then executed.

The if_code and else_code blocks consist of exactly one statement. But that one statement can be a null statement (which would be the case if a semicolon were accidentally placed after the closing parentheses of the test expression and/or the else keyword, a single statement, or a compound statement. An example of the latter case, which is extremely common, is shown below:

prior_code;

 

if (test)

{

    /* if_code block */

    statement_1;

    statement_2;

    ...

    statement_N;

}

else

{

    /* else_code block */

    statement_1;

    statement_2;

    ...

    statement_N;

}

 

next_code;

In many respects, the else portion can be thought of as a completely separate statement which happens to have the constraint that is must immediately follow an if() statement and it's block only executes if the controlling if() statement's block did not.


The switch() Statement

The syntax of the switch() statement is as follows:

prior_code;

 

switch(test)

{

    case constant1:  statement 1;

                     statement_2;

                     break;

    case constant2:  statement_3;

    case constantN:  statement_4;

                     break;

    default :        statement_5;

                     statement_6;

}

 

next_code;

After the prior_code block as finished, the test expression, which can be any expression that yields an integer value, is evaluated. That value is then compared to the integer constant associated with the first case label in the code block controlled by the switch() statement. If it doesn't match, it compares it to the next case label. This continues until either a match is found or the entire list of case labels have been examined.

If a match is found, program control is transferred to the statement immediately following the matching case label. Execution then continues until either the end of the code block is reached or a break statement is encountered. A break statement forces execution to jump out of the block and proceed directly to the next_code block.

If a match is not found, then program control is transferred to the statement following the optional default label, if their is one. If there isn't a default label, the entire block is skipped and control immediately passes to the next_code block.

The constants associated with each case label must be unique, integer constants. They must be unique in that no other case label in the same switch statement can have the same value. They must be integers - which character constants are. They must be constants in that the compiler - at compile time - must be able to evaluate any expression that is there.

The case labels can appear in any order, but the default label, if it exists, must appear last.

Notice in the above example that if the case associated with constant2 is selected, then both statement3 and statement4 will be executed. The fact that statement4 is associated with the constantN label is irrelevant. Read again what the description says: "Execution then continues until either the end of the code block is reached or a break statement is encountered." Is says nothing about anything happening if or when another case label is encountered.


The ?: Conditional Operator

The conditional operator is a special form of an if/else structure that can appear in an expression.

 

The syntax for this operator is as follows:

test? T_expr : F_expr

If  the test expression, which can be any expression that yields an value, is True (anything other than zero), then the result of the entire expression is whatever the result of the T_expr expression is. The F_expr expression is never evaluated. In contrast, if the test expression evaluates as False (exactly zero) then the T_expr expression is never evaluated and the result of the enture expression is whatever the result of the F_expr expression is.

Example: Print a plus or minus sign depending on whether a value is positive or negative:

putc( (x < 0)? '-' : '+', stdout);

If (x < 0) True, the this statement essentially becomes:

putc( '-', stdout);

Otherwise it essentially becomes:

putc( '+', stdout);