C Ternary Operator
The C ternary operator is a compact way to choose one of two expression values. It is often used when an if...else statement would only assign, return, or print one of two alternatives.
Its official name is the conditional operator, and it is the only C operator that uses three operands. Used well, it makes simple decisions concise; used carelessly, it can make code hard to read.
Overview: How It Works
The ternary operator has this idea: test a condition, then evaluate one expression if the condition is true and a different expression if the condition is false. The result of the whole expression is the selected value.
In C, the condition follows the same truth rule used by if: 0 is false, and any nonzero value is true. A comparison such as age >= 18 produces an integer truth value, so it works naturally as the condition. Plain variables also work: items ? "yes" : "no" chooses the first string when items is nonzero.
The important difference from if...else is that the ternary operator is an expression, not a statement. That means it produces a value and can appear inside an assignment, a function argument, a return statement, or a larger expression. An if...else controls blocks of statements; the ternary operator chooses between expression results.
Only the selected branch is evaluated. If the condition is true, C evaluates the expression after ? and skips the expression after :. If the condition is false, it does the opposite. This matters when the branches call functions, modify variables, or contain operations that would be unsafe for one case.
The type of the result is determined from the second and third operands. When both choices have the same type, the result has that type. When they are arithmetic types, C applies the usual arithmetic conversions. For example, choosing between an int and a double produces a double result. This is useful, but it can also surprise you if you expected the result to stay an integer.
Syntax
The general form is:
result = condition ? value_if_true : value_if_false;
| Part | Meaning |
|---|---|
condition |
An expression tested using C truth rules. Zero is false; nonzero is true. |
? |
Separates the condition from the expression used when the condition is true. |
value_if_true |
The expression evaluated and returned when the condition is true. |
: |
Separates the true expression from the false expression. |
value_if_false |
The expression evaluated and returned when the condition is false. |
The ternary operator has low precedence, lower than most arithmetic and comparison operators but higher than assignment. Still, parentheses are often worth using when the expression is part of something larger.
Examples
Example 1: Assigning the larger value
#include <stdio.h>
int main(void)
{
int a = 14;
int b = 9;
int larger = (a > b) ? a : b;
printf("Larger: %d\n", larger);
return 0;
}
Output:
Larger: 14
The condition a > b is true, so the expression after ? is chosen. The value of a is assigned to larger. This is a classic ternary use because both branches are simple values.
Example 2: Choosing text for output
#include <stdio.h>
int main(void)
{
int passed = 1;
printf("Result: %s\n", passed ? "pass" : "fail");
return 0;
}
Output:
Result: pass
Here the condition is the variable passed itself. Since it contains 1, it is true. The selected expression is a string literal, and printf receives that chosen pointer for the %s conversion.
Example 3: Returning a value from a function
#include <stdio.h>
int clamp_to_zero(int value)
{
return (value < 0) ? 0 : value;
}
int main(void)
{
printf("%d\n", clamp_to_zero(-5));
printf("%d\n", clamp_to_zero(12));
return 0;
}
Output:
0
12
The function returns 0 for negative input and the original value otherwise. This is concise because the entire decision is about one returned value. If each branch needed several statements, an if...else would be clearer.
Example 4: Only one branch is evaluated
#include <stdio.h>
int main(void)
{
int denominator = 0;
int numerator = 20;
int result = (denominator != 0) ? numerator / denominator : 0;
printf("Result: %d\n", result);
return 0;
}
Output:
Result: 0
The division branch is not evaluated because denominator != 0 is false. This prevents division by zero. The ternary operator can be useful for guarded expressions, but do not hide complicated safety logic inside a dense one-liner.
How It Works Step By Step
Consider int larger = (a > b) ? a : b;. First, C evaluates a > b. The result is compared with zero according to C truth rules.
If the condition is true, C evaluates a and uses that value as the result of the conditional expression. It does not evaluate b as the false branch. If the condition is false, C evaluates b instead and skips a as the true branch.
After the selected expression has a value, the assignment stores that value in larger. The ternary operator itself does not create a new variable or special storage. It is just an expression whose value is computed before the surrounding assignment, argument passing, or return statement continues.
When the two result expressions have different arithmetic types, C chooses a common type. For example, flag ? 10 : 2.5 has a double result because 10 can be converted to double. If you print or store that result, use a matching type and format specifier.
Common Mistakes
Using the ternary operator for large blocks of work
The ternary operator chooses between expressions. It is not a good replacement for every if...else. If each branch needs several statements, variable updates, logging, or error handling, use regular blocks.
Forgetting about precedence
Code such as printf("%d", a > b ? a : b); works, but larger expressions become harder to read quickly. Parentheses around the condition, as in (a > b) ? a : b, make the decision visible and prevent mistakes when the expression is later changed.
Nesting too many ternary operators
A nested expression can classify more than two cases, but it becomes unreadable fast. This compiles:
#include <stdio.h>
int main(void)
{
int score = 72;
char grade = (score >= 90) ? 'A' : (score >= 80) ? 'B' : (score >= 70) ? 'C' : 'F';
printf("Grade: %c\n", grade);
return 0;
}
Output:
Grade: C
Although the program is valid, an if...else if...else chain is usually easier to scan for grading rules. Use nested ternaries only when they remain clearly readable.
Expecting both branches to run
Only one branch is evaluated. Do not put required side effects in both choices and expect them both to happen. If the side effects matter, write explicit statements so the execution order is obvious.
Best Practices
- Use the ternary operator when choosing between two simple expression values.
- Prefer
if...elsewhen branches contain multiple statements or important side effects. - Put parentheses around complex conditions to make the expression easier to read.
- Keep both result expressions compatible in type, especially when assigning or printing the result.
- Avoid deeply nested ternary expressions; they are legal but often difficult to maintain.
- Remember that only the selected branch is evaluated, which can be useful for guarded calculations.
- Do not use the ternary operator just to appear clever. Readability is more important than saving lines.
Practice Exercises
- Create two integers,
xandy. Use the ternary operator to store the smaller value in a variable namedsmaller, then print it. - Write a program with an
int temperature. Printcoldwhen it is below15, otherwise printwarm. - Write a function
absolute_valuethat returns the positive version of an integer using one ternary expression. Test it with a negative and a positive value.
Summary
- The ternary operator has the form
condition ? true_expression : false_expression. - It is an expression, so it produces a value and can be used inside assignments, returns, and function arguments.
- The condition uses normal C truth rules:
0is false and nonzero is true. - Only the selected branch is evaluated.
- The result type depends on the two branch expressions and C’s conversion rules.
- Use ternary expressions for small value choices, and use
if...elsefor larger control-flow decisions.
