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 doesnt 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 its p, theres no point in checking to see if its 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: ==, !=
&&
||