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.
}
聽