If-statements

Alter flow of control from sequential execution of statements

Allow us to skip parts of the program

Whether/what to skip depends on some condition


2 kinds of if-statements: "if-then" or "if-then-else"

Syntax:

if (condition)
   statement;
[else statement;]
statement can be a single C statement
or a series of statements enclosed in
braces. We indent the statement for readability

Examples:

if (x == y)
  printf ("%d is equal to %d", x, y);

if (x == y) 
  printf ("%d is equal to %d", x, y);
else
  printf ("%d is not equal to %d", x, y);

If-then statements

If we need to do something under a given condition and nothing otherwise, set up the condition so that the action is performed in the "then-part", rather than the "else-part".

Good: Not so good:
if (x == y)
printf ("%d is equal to %d", x, y);
if (x != y)
/* do nothing */;
else
printf ("%d is equal to %d", x, y);

Notice that the condition for the first example is the negation of the condition for the second example: !(x != y) is the same as (x == y)


If-then statements
Remember: The C compiler doesn't care about indentation

if (value == 10) 
  printf ("value is okay\n");
  printf ("Good work!\n");

"Good work!" is always printed.

if (value == 10){ 
  printf ("value is okay\n");
  printf ("Good work!\n");
}

"Good work is printed only if value is 10


Nested if-then-else statements

Each if-statement is itself a statement, so it can be (part of) the

statement in an if-statement. Nesting can go on indefinitely:

if condition1
  if condition2
    statement;
  else {
    if condition3
      statement;
    else 
      statement;
  } 
else
  statement;

"Attachment Problem"

If the nesting is deep, how do you know which ELSE goes with which IF? An ELSE always "attaches" to the nearest preceding IF that is not already attached to an ELSE:

if condition1 	/* if #1 */
  if condition2 /* if #2 */
    statement;
  else 		/* belongs to #2 */
    statement;

Nested if-then-else statements
Indentation doesn’t affect the "attachment of IFs and ELSEs:

if condition1 	/* if #1 */
  if condition2 /* if #2 */
    statement;
else  		/* still belongs to #2 */
  statement;

To force the else to attach to the first if, you must use braces:

if condition1         /* if #1 */
{
  if condition2         /* if #2 */
  statement;
}
else 
  statement /* belongs to #1 */

Sequential if-then statements vs. if-then-else

If you have a series of if-then statements, each one will always be executed:

if (command == ‘p’)
  /* code for command ‘p’ */;
if (command == ‘i’) 
  /* code for command ‘i’ */; 

In this case, since a command can only be one thing at a time, this is inefficient. Once we know it’s ‘p’, there’s no point in checking to see if it’s ‘i’!


Sequential if-then statements vs. if-then-else

If conditions are mutually exclusive, use if-then-else:

if (command == ‘p’)
  /* code for command ‘p’ */;
else if (command == ‘i’) 
  /* code for command ‘i’ */; 

Sequential if-then statements

If conditions are not mutually exclusive, you should use sequential if-statements.
Suppose we want to print messages to tell which of 3 variables are the same:

if (x == y)
  printf ("x = y");
if (x == z)
  printf ("x = z");
if (y == z)
  printf ("y = z");

Efficiency

Simplify! Don't put the same code in both the then-part and the else part.
Example:

scanf ("%c", &response);
if (response == 'a') {
  printf ("You chose an apple\n");
  printf ("What else do you want?\n");
}
else {
  printf ("You chose an orange\n");
  printf ("What else do you want?\n");
}
Simplified:
scanf ("%c", &response);
printf ("You chose an ");
if (response == 'a')
  printf ("apple\n");
else printf ("orange\n");
printf ("What else do you want?\n");

Efficiency
Avoiding if-statements
Skipping code takes time, so avoiding an if-statement is a good idea whenever it's possible
When an if-statement is just assigning a value to a boolean-valued variable, you can be more
efficient:

Inefficient Efficient
int count, done;
if (count > 10)
  done = TRUE;
else done = FALSE; 
int count, done;
done = count > 10;
int temperature, tooCold, 
    snowLikely;
if (temperature <= 0) {
  tooCold = TRUE;
  snowLikely = FALSE;
}
else {
  tooCold = FALSE;
  snowLikely = TRUE;
}
int temperature, tooCold, 
    snowLikely;
tooCold = temperature <= 0;
snowLikely = !tooCold;

Compound Conditions

Three boolean operators allow us to form compound conditions:
AND:
condition1 && condition2
both conditions must be true for the expression to be true

OR:
condition1 || condition2
if either condition is true (or both are), the expression is true

NOT:
!condition

The condition must be false (it must evaluate to 0) for the expression to be true


Precedence of operators (from highest to lowest):

!
relational operators: <, >, <=, >=
relational operators: ==, !=
&&
||