Objects First


More Advanced Features of C

A Ternary Operator

C has many unary operators (operators that take one operand):
OperatorNameExample
!Logical not !((x>a)&&(y>b))
~Complement ~b
&Address of &x
and plenty of binary ones!

But it is almost unique among programming languages in having a ternary one - one that takes three operands.

cond ? expT : expF
The ? operator evaluates cond, if it is true, it evaluates expT and returns it as the value of the ? expression. If cond evaluates to false, it evaluates expF and returns it as the value of the expression. This operator is, of course, entirely redundant: the same effect can be achieved with an
if( cond ) { .. } else { .. }.
However it does allow one to write some very compact expressions and thus is quite popular with C programmers (many of whom seem to have chosen C for its terse syntax, which allows them to
  1. be lazy and
  2. appear incredibly clever.
One common use of the ? operator is the definition of MAX and MIN "functions":
#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))
Remembering that the pre-processor will expand MAX(a,b) as text, it can be seen that this MAX "function" works equally well for int, float and double.

Although it is somewhat cryptic and one could argue that the ? operator merely adds to the difficulty of deciphering the meaning of the average C program with all its single character operators and other short-cuts, the ? operator does allow some compact coding which would be unnecessarily verbose otherwise. For example, if you're annoyed by programs that print:

10 cats and 1 dogs
instead of
10 cats and 1 dog
You can fix this by the following artifice:
printf("%d cat%c", n_cats, (n_cats>1)?'s':'\0');
(n_dogs>0)?printf("%d dog%c", n_dogs, (n_dogs>1):'s':'\0'):printf("");
These statements rely on the fact that a null character ('\0') will be ignored by any output device. The second statement, while perfectly valid C, is starting to move into questionable waters. Many would argue that:
printf("%d cat%c", n_cats, (n_cats>1)?'s':'\0');
if (n_dogs>0) printf("%d dog%c", n_dogs, (n_dogs>1)?'s':'\0');
is better - and I would probably agree with them! However the extra if .. necessary to avoid an unneeded 's' in the output definitely adds to the sheer volume of the code compared to this convenient use of the ? operator.

Continue on to Functions as Parameters Back to the Table of Contents
© John Morris, 1998