Writing a conditional involves creating a logical expression that evaluates to true (non-zero) or false (zero). C evaluates these expressions using a specific set of rules, and the result directly determines the consequent branch of code that gets executed.
Writing and Evaluating Conditionals in C 馃
This topic focuses on the heart of decision-making in C: the conditional expression itself. Understanding how to write these expressions and how the compiler evaluates them is key to controlling your program's flow.
1. Writing a Conditional Expression
A conditional expression is built using relational and logical operators to form a question that results in a true (non-zero) or false (zero) answer.
路聽聽聽聽聽聽聽聽 Relational Operators: Used to compare two values.
|
Operator |
Meaning |
Example |
|
|
Is equal to |
|
|
|
Is not equal to |
|
|
|
Is greater than |
|
|
|
Is less than |
|
|
|
Is greater than or equal to |
|
|
|
Is less than or equal to |
|
聽
路聽聽聽聽聽聽聽聽 Logical Operators: Used to combine one or more relational expressions.
|
Operator |
Meaning |
Example |
|
|
Logical AND - True only if BOTH operands are true. |
|
|
` |
` |
|
|
|
Logical NOT - Inverts the truth value of its operand. |
|
聽
2. The Evaluation Process
C evaluates conditional expressions based on a strict order of operations.
路聽聽聽聽聽聽聽聽
Precedence: Relational operators (>, <, etc.) have higher precedence than equality operators (==, !=), which in turn have higher precedence than logical operators (&&, ||). && has higher precedence than ||. When in doubt, use parentheses () to enforce the order you want.
路聽聽聽聽聽聽聽聽
Short-Circuit
Evaluation: This is a crucial rule
for && and ||.
o聽聽聽 For A && B, if A is false, the expression cannot be true, so B is never evaluated.
o聽聽聽 For A || B, if A is true, the expression must be true, so B is never evaluated.
Example of Evaluation
Consider the
expression: if
(age < 18 || has_permission == 0 && is_vip == 1)
1.聽聽 Precedence: && has higher precedence than ||, so it is grouped first: if (age < 18 ||
(has_permission == 0 && is_vip == 1))
2.聽聽 Evaluation:
o聽聽聽 The sub-expression age < 18 is evaluated.
o聽聽聽 If it is true, the short-circuit rule for || applies,
and the entire right-hand side (has_permission == 0 && is_vip ==
1) is skipped. The
condition is true.
o聽聽聽 If age < 18 is false, the right-hand side is then
evaluated to determine the final result.
3. Consequent Branching
The consequent branch is the block of code that is executed as a result of the conditional expression evaluating to true.
C
if (is_logged_in == 1) {
聽聽聽 // This block is the "consequent branch".聽聽聽 // It only runs if the condition is true.聽聽聽 printf("Welcome back!\n");} else {聽聽聽 // This is the "alternative branch".聽聽聽 printf("Please log in.\n");}The
link between the evaluation and the branch is direct: a non-zero result
triggers the if block; a zero result triggers the else block (if one exists).
4. Common Patterns and Pitfalls
路聽聽聽聽聽聽聽聽
The Assignment
Bug: = vs. ==
o聽聽聽 Incorrect: if (x = 5)
o聽聽聽 Evaluation:
This does not compare x to 5.
It assigns 5 to x. The
value of the entire expression is 5, which is non-zero, so the condition is always true.
o聽聽聽 Correct: if (x == 5)
路聽聽聽聽聽聽聽聽
Comparing with
true
o聽聽聽 Verbose: if (is_valid == 1)
o聽聽聽 Idiomatic C:
if
(is_valid) (Checks if is_valid is any non-zero value)
o聽聽聽 Verbose: if (is_valid == 0)
o聽聽聽 Idiomatic C:
if
(!is_valid) (The ! operator inverts the truth value)
路聽聽聽聽聽聽聽聽 Floating-Point Comparisons
o聽聽聽 Incorrect: if (result == 0.3)
o聽聽聽 Evaluation: Due to small precision errors in how floating-point numbers are stored, this comparison is unreliable and will often fail even if the values are mathematically equal.
o聽聽聽 Correct: Check if the absolute difference is within a small tolerance (epsilon).
C
#include <math.h>const double EPSILON = 0.00001;if (fabs(result - 0.3) < EPSILON) {聽聽聽 // The values are close enough to be considered equal.}聽