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
- conditions can be true or false
we do one thing when the condition is true,
something else when the condition is false
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
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 |