Well, I meant that false in general. Like: Is ((1 == 2) == 0)?
If I may use a rather ... earthy analogy (which should at least be
unforgettable!
), you can consume many kinds of food and drink:
plain water, orange juice, potatos, chicken, perhaps even lutefisk.
But your digestion of these inputs will only ever produce two kinds
of output, which some call "number one" and "number two"; or as a
friend of mine once called them, "stream output" and "core dumps".
C's relational and logical operators can consume many kinds of
input, but produce only two outputs. For something like:
if (x) {
truestuff();
} else {
falsestuff();
}
C will take the truestuff() branch if x is not zero, and the
falsestuff() branch if x is zero. But for:
int result = (x == y);
result will be 1 -- just just "any nonzero value", but exactly 1
-- if x == y, and 0 (the only "false" value) if x != y.
Note that the functions in <ctype.h>, such as isdigit() and isalpha(),
are *not* required to produce just 0 or 1, and often do not.
Because the logical operators force "any nonzero value" to become
1, and because the "!" (logical-not) operator is its own inverse,
you can use a double negation to "normalize" a boolean result:
int normalized = !!f();
Now "normalized" is 1 if f() returned nonzero, and 0 if f()
returned 0. If for some strange reason you want a "normalized"
version of, e.g., isalpha(), you can write:
int one_if_isalpha = !!isalpha(ch);
The same works for the other logical operators (&& and ||), so you
can also normalize by &&-ing with 1, or ||-ing with 0:
int normalized_via_AND = f() && 1;
int normalized_via_OR = f() || 0;
but I think these are even odder-looking than the "!!" normalization
method.
I leave it up to the reader to decide which of 0 and 1 correspond
to the, er, "stream output" and "core dump".