Conditionals


Introduction

The C language has conditional statements, also called selection statements (and colloquially called if statements). Essentially, depending on a certain condition, a program can decide which statements to execute and which ones to ignore.

The simplest selection statement is the if statement:

if ( expression )
  statement
Note that the parentheses after the if keyword are required.

You read this as:

"If expression is true, then execute statement."
You could also read it as:
"If expression is false, then do not execute statement." (In which case statement is simply skipped.)
Notes about expression: Relational operators:
< less than
> greater than
<= less than or equal to
>= greater than or equal to
Equality operators:
Operator Meaning
== equal to
!= not equal to
Note that the relational operators have higher precedence than the equality operators. (Operators in C)

Some example usage:

Statement Correct/Incorrect
if (a > 5)
  statement
Correct
if (a)
  statement
Correct
if (1)
  statement
Correct
if a < 5
  statement
Missing parentheses
IF (a < 5)
  statement
Wrong 'if' keyword
if (a < 5) then
  statement
No 'then' keyword
if ()
  statement
Missing expression
The value of a relational expression is either 0 (false) or 1 (true).

Examples of the relationship between false/0 and true/1:

int a = 5;
int b = 0;

printf("Value of a > b is %i\n", a > b);
printf("Value of a < b is %i\n", a < b);
printf("Value of a == b is %i\n", a == b);
printf("Value of a == a is %i\n", a == a);
printf("Value of b == b is %i\n", b == b);
printf("Value of a != a is %i\n", a != a);
printf("Value of a > a is %i\n", a > a);
printf("Value of b > b is %i\n", b > b);
Output:
Value of a > b is 1
Value of a < b is 0
Value of a == b is 0
Value of a == a is 1
Value of b == b is 1
Value of a != a is 0
Value of a > a is 0
Value of b > b is 0
Logical operators: (the precedence is accurate as well)
Operator Meaning
! logical not (negation)
(unary operator)
&& logical and
|| logical or
Boolean Truth Tables:
a b a && b a || b
false false false false
false true false true
true false false true
true true true true
a b a && b a || b
0 0 0 0
0 1 0 1
1 0 0 1
1 1 1 1

Notes about these operators:

Note: Remember, the logical operators, || and && are different from the other operators we've seen. These operators enable short-circuit evaluation so it is possible that a portion of the expression could be skipped entirely. This means that if there are any side-effect operators in the part of the expression that is skipped, those side-effects will NOT occur.


More on the if Statement

We've seen the simplest form of the if statement:
if ( expression )
  statement
where statement is exactly one statement. If you want to execute multiple statements, you need to include curly braces around them:
if ( expression )
{
  statements
}
The statements (plural) means more than one statement. Example:
  /* single statement */
if (a > b)
  printf("a = %i, b = %i\n", a, b);

  /* compound statement */
if (a > b)
{
  printf("a = %i, ", a);
  printf("b = %i\n", b);
}
Note that there is no semicolon after the closing curly brace. (But each statement inside the braces ends with a semicolon.) Also, it doesn't hurt to put a single statement inside curly braces:
  /* Braces unnecessary, but fine. */
if (a > b)
{
  printf("a = %i, b = %i\n", a, b);
}
This is also legal:
  /* Pointless, but fine. */
if (a > b)
{
}
However, without the braces, you can't have an empty statement. You'll need at least a semicolon:
  /* Pointless again, but legal. */
if (a > b)
    ;
Watch out for this common beginner's error which claims that 0 is greater than 5:
int a = 5;
int b = 0;

if (b > a);  /* Trailing semicolon */
  printf("b is greater than a\n");


The else Clause

Another form of the if statement includes an optional else clause:
if ( expression )
  statement1
else 
  statement2
This reads as: "If expression is true, execute statement1, otherwise, execute statement2. This is mutually exclusive. Either statement1 or statement2 will get executed, but not both (or neither).

Either of the statements (or both) can be compound as well:

if ( expression )
{
  statements
}
else 
  statement
if ( expression )
  statement
else 
{
  statements
}
if ( expression )
{
  statements1
}
else 
{
  statements2
}

Example:

int average = 85;
char grade;

if (average >= 70)
{
  grade = 'P';
  printf("You passed. Your average is %i%%.\n", average);
}
else
{
  grade = 'F';
  printf("You didn't pass. Your average is %i%%\n", average);
}


Nested if Statements

Sometimes we need to perform more than one test to determine the path our program will take. If the conditionals are mutually exclusive, we can cascade or nest the if statements.

Examples:

Non-nestedNested (cascading)Nested (no formatting)
if (average >= 90)
  grade = 'A';
if (average >= 80)
  grade = 'B';
if (average >= 70)
  grade = 'C';
if (average >= 60)
  grade = 'D';
if (average < 60)
  grade = 'F';
if (average >= 90)
  grade = 'A';
else 
  if (average >= 80)
    grade = 'B';
  else 
    if (average >= 70)
      grade = 'C';
    else 
      if (average >= 60)
        grade = 'D';
      else
        grade = 'F';
if (average >= 90)
  grade = 'A';
else 
if (average >= 80)
  grade = 'B';
else 
if (average >= 70)
  grade = 'C';
else 
if (average >= 60)
  grade = 'D';
else
  grade = 'F';

Can you see why the non-nested version will possibly execute slower than the nested version (besides being incorrect)?

The proper way to format nested if statements in this class:

if (average >= 90)
  grade = 'A';
else if (average >= 80)
  grade = 'B';
else if (average >= 70)
  grade = 'C';
else if (average >= 60)
  grade = 'D';
else
  grade = 'F';
Remember that the compiler doesn't care about formatting and will actually see this, all on one line:
if (average >= 90) grade = 'A'; else if (average >= 80) grade = 'B'; else if (average >= 70) grade = 'C'; else if (average >= 60) grade = 'D'; else grade = 'F';
In fact, can you take out all of the spaces as well? If not, which ones can you take out?
Example: if(average>=90)grade='A';else if(average>=80)grade='B;else if(average>=70)grade='C';else if(average>=60)grade='D';else grade='F';


The "Dangling" else

This doesn't print out what you might expect:
if (average < 90)
  if (average < 60)
    printf("Failing\n");
else
  printf("An A student!\n");
If we change the formatting, we can see the problem more clearly.
if (average < 90)
  if (average < 60)
    printf("Failing\n");
  else
    printf("An A student!\n");
Again, compilers don't need any formatting, but humans do.
if (average < 90)
{
  if (average < 60)
    printf("Failing\n");
}
else
  printf("An A student!\n");
The rule for matching up if and else is:
The else matches the closest (previous) if that hasn't already been matched.
You override this behavior through the use of braces, as shown above.


The switch Statement

The switch statement is similar to nested if ... else ... statements. The most common form of the switch statement looks like this:
switch ( expression )
{
  case constant_expression1 : 
    statements1
    break;
  case constant_expression2 : 
    statements2
    break;
  . . .
  case constant_expressionN : 
    statementsN
    break;
}
An example showing both a nested if ... else ... statement and a switch statement. The result is the same. However, when you have a larger number of conditions, the switch statement may execute faster.

Nested ifswitch
if (year == 1)
  printf("Freshman\n");
else if (year == 2)
  printf("Sophomore\n");
else if (year == 3)
  printf("Junior\n");
else if (year == 4)
  printf("Senior\n");
switch (year)
{
  case 1: 
    printf("Freshman\n");
    break;
  case 2: 
    printf("Sophomore\n");
    break;
  case 3: 
    printf("Junior\n");
    break;
  case 4: 
    printf("Senior\n");
    break;
}
/* break statement jumps to here */

Notice that if the value of year is not one of the values tested, nothing will be printed. If you want a catch-all condition, you would use an else clause in the if statement and for the switch statement, use a default:
Nested ifswitch
if (year == 1)
  printf("Freshman\n");
else if (year == 2)
  printf("Sophomore\n");
else if (year == 3)
  printf("Junior\n");
else if (year == 4)
  printf("Senior\n");
else
  printf("Invalid year\n");
switch (year)
{
  case 1: 
    printf("Freshman\n");
    break;
  case 2: 
    printf("Sophomore\n");
    break;
  case 3: 
    printf("Junior\n");
    break;
  case 4: 
    printf("Senior\n");
    break;
  default: 
    printf("Invalid year\n");
    break;
}
/* break statement jumps to here */

Notes:

Boolean Types

As was stated before, C doesn't have a boolean type. Instead, it uses 0 to represent false and 1 (or non-zero) to represent true.

Using one and zero, the meaning isn't clear:

int value = 1;

if (value == 1)
{
  /* do something if value is true */
}

if (value == 0)
{
  /* do something if value is false */
}
We can "create" our own boolean values and type:
#define FALSE 0
#define TRUE  1
#define BOOL int
And use these types in our programs:

Explicit comparisonsImplicit comparison
BOOL value = TRUE;

if (value == TRUE)
{
  /* do something if value is true */
}

if (value == FALSE)
{
  /* do something else if value is false */
}
BOOL value = TRUE;

if (value)
{
  /* do something if value is true */
}

if (!value)
{
  /* do something else if value is false */
}