Flow of Control

(read chapter 3)

Boolean Expressions and Operators

C has no boolean type -- it uses integers instead:

/* legal C syntax */
if (1) count++;

Useful constant definitions:

const int TRUE = 1;
const int FALSE = 0;
If you use these constants, never write something like:
int b = 7;

if (b == TRUE) count++;

Return to Table of Contents

Relational (Comparison) Operators

C syntax for relational operators
operatormeaning
< less than
<= less than or equal
> greater than
>= greater than or equal
== equality
!= inequality

All about comparisons:

Return to Table of Contents

Boolean Operators and Compound Boolean Expressions

operator meaning example
&& logical and ((1 <= a) && (a <= 10))
|| logical or ((a == 1) || (a == 2))
! logical negation (!(a == 1))
equivalent to (a != 1)

Example: to test whether the value of a double variable d1 is within 0.001 of the value of another double variable d2:

((d1 >= (d2 - 0.001)) && (d1 <= (d2 + 0.001)))

Operators && and || are short circuit - they sometimes don't evaluate their second argument. E.g. let exp be any expression of type int:

(0 && exp) is false
(1 || exp) is true

Short circuit evaluation is often useful. E.g. searching in an array:

  while ((index < MAX) && (A[index] != 3))
    index++;

Return to Table of Contents

if Statements

The if statement is used when a segment of code may or may not be executed, depending on the value of some condition. It has two forms:

if (boolean expression) block

if (boolean expression) block1
else block2

E.g.:

  int arg, result;

  /* something gets assigned to arg here */

  /* find absolute value of arg and 
     put it in result */

  if (arg < 0) result = -arg;
  else result = arg;

E.g:

  int arg, result;

  /* something gets assigned to arg here */
  
  /* assign absolute value of arg to arg */

  if (arg < 0) arg = -arg;
E.g:
  int arg, result;

  /* something gets assigned to arg here */

  /* check if result is set to the 
     absolute value of arg.  If not,
     set it and report the problem. */

  if ((arg < 0) && (result != -arg))
    { printf("result was not set\n");
      result = -arg;
    } 
  else if ((arg >= 0) && (result != arg))
    { printf("result was not set\n");
      result = arg;
    } 

One common error is to forget { } around a block of several statements:

  if (arg < 0)
    printf("arg is negative\n");
    result = -arg;
The assignment statement is not part of the block and so will be executed regardless of the value of arg.

If statements can contain other if statements. See ~taw2/pub/if.c.

More interesting nesting is also possible. To check if a point falls in either of the intervals:

    int point;

/* A */  if (point <= -1) 
/* B */    if (point >= -2)
             printf("point is in range\n");
/* C */  else if (point >= 1)
           if (point <= 2)
             printf("point is in range\n");
 
/* D */  
This will do something unexpected! If (point > -1), execution jumps to line D - no message is printed even if the point is in the positive part of the range. In C, an else is matched with the nearest preceding if not already matched by an else. Here the else (line C) matches the if in line B, not the one in line A as we probably intended. One way to fix this problem is to enclose the if starting in line B in { }.
    int point;

/* A */  if (point <= -1) 
/* B */    {if (point >= -2)
             printf("point is in range\n");}
/* C */  else if (point >= 1)
           if (point <= 2)
             printf("point is in range\n");
 
/* D */  

Short circuit evaluation can be used with if statements to avoid run-time and logical errors:

  if ((count != 0) && (sum/count > 10))
    sum++;
Executing this statement will not cause a run-time error, even when count is equal to 0.

Return to Table of Contents

if Expressions

(see conditional assignment in text)

An if statement decides which block of code to execute based on the value of a boolean expression. An if expression computes a value based on a boolean expression.

Syntax:

(boolean expr)? expr1:expr2

If boolean expr is true (not 0), this expression has the value of expr1. Otherwise, it has the value of expr2.

E.g.:

  int arg, result;

  result = (arg < 0)?-arg + 3: arg + 3;
assigns 3 more than the absolute value of arg to result.

An if expression can be used anywhere an expression can be used:

E.g.:

  printf("The absolute value is: %d\n",
         (arg < 0)?-arg:arg);

Return to Table of Contents

switch Statements

Syntax of switch:

  switch (variable) {
    case value1: group1
                 break;
    case value2: group2
                 break;

                 .
                 .
                 .

    case valueN: groupN
                 break;
    /* next 2 lines are optional */
    default:     groupD
                 break;
  } /* end switch */
where:

This switch is equivalent to:

  if (variable == value1) {
    group1
  } else if (variable == value2) { 
    group2
  } else 
      .
      .
      .
  
  } else if (variable == valueN) { 
    groupN
  } else {
    groupD
  }

See ~taw2/pub/switch.c.

The break statement causes following cases to be ignored - "control jumps out of the switch". If we remove all of the break statements from this program, it prints 9 *s for x == 2, because the case for x == 3 and the default case are also executed.

Forgetting break statements is a common cause of errors.

Return to Table of Contents

Loops

for Loops

Syntax:

for (initialize counter; boolean expression; change counter) block

E.g. printing the even numbers from 2 to 10:

  int counter;

  for (counter = 2; counter <= 10; counter += 2)
    printf("%d\n", counter);

Note that the counter variable is changed after the block is executed.

E.g. print and sum the odd numbers from 15 to 1

  int counter, sum=0;
  /* initialize sum to 0 */

  for (counter = 15; counter >= 1; counter -= 2) {
    printf("%d\n", counter);
    sum += counter;
  }
  printf("The sum is %d\n", sum);

See ~taw2/pub/ave.c for another example.

Return to Table of Contents

while Loops

while loops are usually used when the number of iterations isn't known in advance (indefinite iteration).

Syntax:

while (boolean expression) block

The boolean expression is re-evaluated at the beginning of each iteration, and the block is executed until the boolean expression becomes false. If the boolean expression is false initially, the block is never executed.

The example program in ~taw2/pub/enternum.c forces the user to enter a number between 1 and 10. Control-C can be used to break out of such a program.

The usual form for a while loop is:

  initialize variables
  while (boolean expression) {
    body (changes some variable
      occurring in the boolean
      expression)
  }

See ~taw2/pub/ave2.c for another example.

Return to Table of Contents

do while Loops

Syntax:

do block while (boolean expression);

The boolean expression is not tested until the "bottom" of the loop, so the block is always executed at least once. See ~taw2/pub/ave3.c for an example.

Each of the three kinds of loops can be used whenever a loop is needed, but each is best suited for certain situations:

Return to Table of Contents

Using break and exit()

See ~taw2/pub/usebreak.c for an example.

When the exit() function is executed, it immediately stops (in UNIX terminology, terminates) the execution of the program. In UNIX:

  exit(0); /* normal termination */
  exit(1); /* or any other nonzero int */
           /* signals error termination */

The value used with exit is assigned to the environment variable status. The value of this variable can be printed:

echo $status
or used in more interesting ways.

See ~taw2/pub/useexit.c.

Note that:

  for (;;) {
    body
  }
and
  while (1) (
    body
  }
are infinite loops and can only be terminated by a break or exit() in the body.

Return to Table of Contents