The Fork in the Road

In order to provide a two-way decision structure, C provides the if statement. An example of this statement would be:

if( a < b )
   printf( "a < b\n" ) ;
else
   printf( "a >= b\n" ) ;

This statement corresponds to the flow chart:

Flow chart for previous code fragment

The general syntax for an if statement is:

if( expression )
   statement
or
if( expression )
   statement
else
   statement

In other words, if we don't need to do anything if the condition is false, we don't need to provide an else clause.

We'll take a closer look at the conditional expression later, but for now we'll list some of the expressions you'll need.

a < b - a is less than b
a > b - a is greater than b
a <= b - a is less than or equal to b
a >= b - a is greater than or equal to b
a == b - a is equal to b
a != b - a is not equal to b
For now, take note of the fact that to test for equality, we use a double equals sign (==) instead of a single equals sign. The single equals sign is for assignment. We'll look at the rationale and warn of pitfalls with this in the next part.

There's another aspect of this new statement that is worth a word of caution here. In particular a string of characters such as:

if( a < b )
is not a complete statement. So we don't put a semicolon at the end. It turns out that a line like:
if( a < b ) ;   /* Don't do this */
is legal C; it says that if a is less than b, then we are to do a null or empty statement. There's no good reason to ever do this since the net effect is to do nothing either way. It is almost always the case that a semicolon at the end of an if is a mistake. But since it's legal, the compiler won't tell you about it. (We'll see in Part 4 that null statements do have uses, just not with ifs.)

The last thing to look at here is what do we do if we want to do more than one statement in either the true or else parts of the if? One might think that we can just list several statements one after the other between the if and the else or after the else. Well, that's not quite enough. If that were all we did, how could the compiler tell where our false code ended and the code following the if statement began. Such an approach would also not quite fit with the general form we saw earlier where each branch could have only a single statement. The answer in C is that we can group any statements into a compound statement that can be used anywhere we can use a single statement. We group such statements with braces ({ and }). For example, we might use a code fragment like:

if( a < b ) {
   c = a ;
   printf( "a < b\n" ) ;
}
else {
   c = b ;
   printf( "a >= b\n" ) ;
}

Aside from printing out what the relationship between a and b is, this if statement will also set c to be the smaller of the two a and b. We'll see more about this block structuring in C soon.

Notice also that the code in each branch of an if is usually indented. How one indents varies widely. In the examples in these lab tutorials, indentation is done in increments of three spaces. Other common amounts are two spaces, four spaces and a tab. Such indentation is not a requirement of the language, but is common practice to make the structure clear to the reader.

One last thing before moving on concerns where the braces are placed in the program. There's considerable debate on the best way to lay out the code and in where to put the braces. The style used in this tutorial is that which is used by it's author and is also the style (at least in regards to the braces) that is used in The C Programming Language by Dennis Ritchie and Brian Kernighan.

What does this code output?
x = 5 ;
y = 7 ;
if( x >= y ) {
   if( x != 6 )
      printf( "A" ) ;
   else
      printf( "B" ) ;
}
else {
   if( y != x )
      if( y > 4 )
         printf( "C" ) ;
      else
         printf( "D" ) ;
   else
      printf( "E" ) ;
}

A
B
C
D
E