CIS 1057. Computer Programming in C

Chapter 4. Selection Structures: if and switch Statements


1. Control structures

In a C program, the flow of execution is sequential by default, that is, one statement after another in their order as in the source code of a function.

With various control structures, the order of execution can be different from the sequential order.

There are two major types of non-sequential control structures: selections and loops. This chapter introduces the former, and the next chapter describes the latter.

Control structures are usually used with compound statements. A compound statement is a group of statements between a pair of braces "{ }", and can be seen as a single "macro statement". The body of a function is such a compound statement.


2. Conditions

A (compound) statement can be conditional, that is, executed only when certain condition is satisfied.

A condition can be specified by an operator between two (variable or constant) values. The following list includes the operators:
Operator Meaning Type
< less than relational
> greater than relational
<= less than or equal to relational
>= greater than or equal to relational
== equal to equality
!= not equal to equality
Each condition has a value, which is either 1 (true) or 0 (false). In C, a nonzero integer is treated as "true" when it is used as a condition.

For example, given the following identifiers and their values:

x  power  MAX_POW  y  item  MIN_ITEM  mon_or_dad  num  SENTINEL
-5 1024   1024     7  1.5   -999.0    'M'         999  999
then the values of the following conditions can be determined:
Condition           Value
x <= 0              1
power < MAX_POW     0
x >= y              0
item > MIN_ITEM     1
mon_or_dad == 'M'   1
num != SENTINEL     0
The above simple conditions can be combined into complicated conditions, or logical expressions, using the following logical operators: "&&"(and) "||" (or), "!" (not). IF P and Q are (simple or complicated) conditions, P||Q is true if and only if at least one of the two is true, P&&Q is true if and only if both of the two are true, and !P is true if and only if P is false.

An operator's precedence determines its order of evaluation. In the following, we list the C operators we covered so far, from the highest precedence to the lowest:

function call
! + - (unary)
* / %
+ -
< <= > >=
== !=
Among the operators of the same precedence, the execution order is from left to right, except for the unary operators what are applied from right to left. Parentheses "( )" can be used to change the order of execution.

Whenever possible, C only evaluates part of a logical expression. For example, P||Q is true if P is true, and P&&Q is false if P is false. In both cases, the second operand does not need to be evaluated. This technique is called "short-circuit evaluation".

Beside numbers, characters in C can also be compared by the relational/equality operators, using the alphabetic order. It is system dependent whether an upper-case letter is smaller than a lower-case one.


3. The if statement

The "if" statement is the simplest selection control structure. It has the following general form:
  if (condition)
In this structure, the "else" part is optional. FIGURE 4.4 gives the two corresponding flowcharts.

The program is in FIGURE 4.5.


4. if statement with compound

Both the "statementT" and "statementF" in the if structure can be a compound statement, within "{ }". For example, the program in FIGURE 4.6 switches the values x and y if initially the former is greater than the latter.

A program should work correctly in any condition.


5. Decision steps in algorithms

In an algorithm, a decision step is a choice among alternatives, and is often coded as an if statement.

CASE STUDY: Water Bill Problem

The problem is to compute the water bill of a customer. The bill includes a $35 demand charge, plus a consumption charge of $1.10 for every thousand gallons used. If the customer has unpaid balance, a $2 late charge is assessed as well.

Analysis leads to the structure chart in FIGURE 4.7:

The green arrows in the chart indicate data flow, that is, arguments if the sub-problem is processed by a separate function.

The complete program is in FIGURE 4.8, which contains four functions beside the main function.


6. More problem solving

In a program, the output of one step can be the input of another step.

A new problem is often a variation of an old problem. In that case, to modify the old program may be better than to write a new program.

CASE STUDY: Water Bill with Conservation Requirements

Problem: to modify the water bill program so that customers who fail to meet conservation requirements are doubly charged for the extra amount. The conservation requirement is 95% of the amount used in the same quarter last year.

The function for this calculation is in FIGURE 4.10. The other part of the program should be modified accordingly.


7. Nested if statements and multiple-alternative decisions

There are two common ways to combine two if statements: one within the statementT, or the statementF, of the other. Both are called "nested if statements", and the latter can also be written in the form of "multiple-alternative decisions". Please note that both of them are different from one after the other.

When two or more if statements are put together, the order usually matters. For example, in FIGURE 4.11, the latter conditions all assume the previous conditions are false.

Nested if statements can be used to handle multiple variables, with one if statement for each variable. An example is in FIGURE 4.12 — when the road is "slick", it can either be "icy" or just "wet", depending on temperature.

C associates an else with the most recent incomplete if. Braces should be used to match an else with an earlier if.


8. The switch statement

The switch statement is a better way for multiple-alternative decisions if the selection is based on the value of a variable or simple controlling expression, with a type int or char. The pattern of this statement is:
    switch (expression) {
    case c_1:
        action a_1;
     ... ...

    case c_n:
        action a_n;
In this statement, multiple cases can be combined, as well as multiple actions for the same case.

For example, the switch statement in FIGURE 4.13 allows the user to use a single letter to represent an option.


9. Common errors

Conditions like (0 <= x <= 4) should be rewritten as (0 <= x && x <= 4).

Do not confuse "==" with "=". Condition (x = 10) will always be true, because the value of an assignment is the value assigned, which is non-zero in this case.

Use braces with nested if statements, so that the else part will match the condition properly. Also, use indention will improve readability.

Don't forget to put break between cases in a switch statement.