C
Preprocessor
Introduction
:
} The C preprocessor executes
before a program is compiled.
} Some actions it performs are
◦
the inclusion of other files
in the file being compiled
◦
definition of symbolic constants and
macros
◦
conditional compilation of program code and
◦
conditional execution of preprocessor directives.
} Preprocessor directives
begin with #.
Directive
|
Description
|
#define
|
Substitutes a preprocessor macro
|
#include
|
Inserts a particular header from another file
|
#undef
|
Undefines a preprocessor macro
|
#ifdef
|
Returns true if this macro is defined
|
#ifndef
|
Returns true if this macro is not defined
|
#if
|
Tests if a compile time condition is true
|
#else
|
The alternative for #if
|
#elif
|
#else an #if in one statement
|
#endif
|
Ends preprocessor conditional
|
#error
|
Prints error message on stderr
|
#pragma
|
Issues special commands to the compiler, using a
standardized method
|
#include
Preprocessor Directive :
} #include preprocessor
directive causes a copy of a specified
file to be included in place of the directive.
} The two forms of the
#include directive are:
#include <filename>
#include "filename"
#include "filename"
} The difference between these
is the location the preprocessor begins searches for the file to be included.
} If the file name is enclosed
◦
in quotes, the preprocessor starts
searches in the same directory in which the file/program being compiled (and
may search other locations, too).
◦
This method is normally used to include programmer-defined headers.
◦
If the file name is enclosed in angle
brackets (< and >)—used for standard library
headers—the search is performed in an implementation-dependent manner, normally
through predesignated compiler and system directories.
} The #include directive is
used to include standard library headers
such as stdio.h and stdlib.h and with programs consisting of several source
files that are to be compiled together. Ex: #include <stdio.h>
} A header containing
declarations common to the separate program files is often created and included
in the file.
◦
Ex: #include
<studentstructures.c>
} Examples of such
declarations are structure and union declarations, enumerations and function
prototypes.
#define
Preprocessor Directive:
Symbolic
Constants :
} The #define directive
creates
§ symbolic constants—constants
represented as symbols
§ Symbolic constants enable us
to create a name for a constant and use the name throughout the program.
§ macros—operations are defined
as symbols.
} The #define directive format
is
#define identifier
replacement-text
} When this line appears in a
file, all subsequent occurrences of identifier that do not appear in string
literals will be replaced by replacement-text automatically before the program
is compiled.
} For example,
#define PI 3.14159
replaces every occurrence of
the identifier PI in the program with the constant 3.14159.
} If the constant needs to
be modified throughout the program, it can be modified once in the #define
directive. System does not allow to modify in the subsequent occurrences.
} When the program is
recompiled, all occurrences of the constant in the program will be modified
accordingly.
} By convention symbolic
constants are defined using only uppercase letters and underscores.
Macros :
} A macro is an identifier
defined in a #define preprocessor directive.
} The macro-identifier is
replaced in the program with the replacement-text before the program is
compiled.
} Macros may be defined with
or without arguments.
} A macro without arguments is
processed like a symbolic constant.
} In a macro with arguments,
the arguments are substituted in the replacement text, then the macro is
expanded—i.e., the replacement-text replaces the identifier and argument list
in the program.
} Consider the following macro
definition with one argument for the area of a circle:
} #define PI 3.14159
} #define CIRCLE_AREA( x ) ( (
PI ) * ( x ) * ( x ) )
} Wherever CIRCLE_AREA(x)
appears in the file, the value of x is substituted for x in the
replacement-text, the symbolic constant PI
is replaced by its value (defined previously) and the macro is expanded in the
program.
} For example, the statement
area = CIRCLE_AREA( 4 );
is expanded to
area = ( ( 3.14159 ) * (
4 ) * ( 4 ) );
and the value of the expression is
evaluated and assigned to variable area.
} The parentheses around each
x in the replacement text force the proper order of evaluation when the macro
argument is an expression.
} Symbolic constants and
macros can be discarded by using the #undef preprocessor directive.
} Directive #undef “undefines” a symbolic constant or macro name.
} The scope of a symbolic
constant or macro is from its definition until it is undefined with #undef, or
until the end of the file.
} Once undefined, a name can
be redefined with #define.
Conditional
Compilation:
} Conditional compilation
enables us to control the execution of preprocessor directives
and the compilation of program code.
} Each of the conditional
preprocessor directives evaluates a constant integer expression.
} Cast expressions, sizeof
expressions and enumeration constants cannot be evaluated in preprocessor
directives.
} The conditional preprocessor
construct is much like the if selection statement.
} Consider the following
preprocessor code:
} #if !defined(MY_CONSTANT)
#define MY_CONSTANT 0
#endif
#define MY_CONSTANT 0
#endif
} These directives determine
if MY_CONSTANT is defined.
} The expression defined(
MY_CONSTANT) evaluates to 1 if MY_CONSTANT is defined; 0 otherwise.
} If the result is 0,
!defined(MY_CONSTANT) evaluates to 1 and MY_CONSTANT is defined.
} Otherwise, the #define
directive is skipped.
} Every #if construct ends
with #endif.
} Directives #ifdef and
#ifndef are shorthand for #if defined(name) and #if !defined(name).
} A multiple-part conditional
preprocessor construct may be tested by using the #elif (the equivalent of else
if in an if statement) and the #else (the equivalent of else in an if
statement) directives.
} These directives are
frequently used to prevent header files from being included multiple times in
the same source file.
#error
and #pragma Preprocessor Directives:
} The
#error directive
#error tokens
prints an
implementation-dependent message including the tokens specified in the
directive.
} The
tokens are sequences of characters separated by spaces.
} For
example,
#error 1 - Out of range
error
contains 6 tokens.
} When
a #error directive is processed on some systems, the tokens in the directive
are displayed as an error message, preprocessing stops and the program does not
compile.
} The
#pragma directive
#pragma tokens
causes an
implementation-defined action.
} A
pragma not recognized by the implementation is ignored.
# and ## Operators:
} The # and ## preprocessor
operators are available in Standard C.
} The # operator causes a
replacement text token to be converted to a string surrounded by quotes.
} Consider the following macro
definition:
#define HELLO(x) printf( "Hello, " #x "\n" );
} When HELLO(John) appears in
a program file, it is expanded to
printf( "Hello,
" "John" "\n" );
} The string "John"
replaces #x in the replacement text.
} Strings separated by white
space are concatenated during preprocessing, so the preceding statement is
equivalent to
printf( "Hello,
John\n" );
} The # operator must be used
in a macro with arguments because the operand of # refers to an argument of the
macro.
} The ## operator concatenates
two tokens.
} Consider the following macro
definition:
#define TOKENCONCAT(x, y) x ## y
} When TOKENCONCAT appears in
the program, its arguments are concatenated and used to replace the macro.
} For example, TOKENCONCAT(O,
K) is replaced by OK in the program.
} The ## operator must have
two operands.
Line
Numbers:
} The #line preprocessor
directive causes the subsequent source code lines to be renumbered starting
with the specified constant integer value.
} The directive
#line 100
starts line numbering from 100
beginning with the next source code line.
} A file name can be included
in the #line directive.
Predefined
Symbolic Constants :
} Standard C provides
predefined symbolic constants, several of which are shown in Fig.
} The identifiers for each of
the predefined symbolic constants begin and end with two underscores.
} These identifiers and the defined
identifier (used in Section 13.5) cannot be used in #define or #undef
directives.
} Pre defined symbolic
constants are :
No comments:
Post a Comment