The #defineStatement 307
the preprocessor would replace the occurrence of the defined name PIwith
3.141592654;.The compiler would therefore see this statement as
return 2.0 3.141592654; r;
after the preprocessor had made its substitution, which would result in a syntax error.
A preprocessor definition does not have to be a valid C expression in its own right—
just so long as wherever it is used the resulting expression is valid. For instance, the defi-
nition
#define LEFT_SHIFT_8 << 8
is legitimate, even though what appears after LEFT_SHIFT_8is not a syntactically valid
expression.You can use your definition of LEFT_SHIFT_8in a statement such as
x = y LEFT_SHIFT_8;
to shift the contents of yto the left eight bits and assign the result to x.Of a much more
practical nature, you can set up the definitions
#define AND &&
#define OR ||
and then write expressions such as
if ( x > 0 AND x < 10 )
...
and
if ( y == 0 OR y == value )
...
You can even include a define for the equality test:
#define EQUALS ==
and then write the statement
if ( y EQUALS 0 OR y EQUALS value )
...
thus removing the very real possibility of mistakenly using a single equal sign for the
equality test, as well as improving the statement’s readability.
Although these examples illustrate the power of the #define,you should note that it
is commonly considered poor programming practice to redefine the syntax of the
underlying language in such a manner. Moreover, it can make it harder for someone else
to understand your code.
To make things even more interesting, a defined value can itself reference another
defined value. So the two defines
#define PI 3.141592654
#define TWO_PI 2.0 * PI