View
235
Download
0
Category
Preview:
Citation preview
8/13/2019 BTCS 1223_Chap8_Preprocessor
1/39
BTCS 1223: A DVANCED
P ROGRAMMING :
C HAPTER 8: C P REPROCESSOR
Mohd Saad Bin Hamid
Semester 2 : 2011/2012
8/13/2019 BTCS 1223_Chap8_Preprocessor
2/39
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
3/39
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 , conditionalcompilation of program code and conditionalexecution of preprocessor directives .
Preprocessor directives begin with # and only white-space characters and comments may appear before apreprocessor directive on a line.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
4/39
#include Preprocessor Directive The #include preprocessor directive has been used
throughout this text. The #include 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#include#include#include #include#include#include#include "filename""filename""filename""filename"
The difference between these is the location thepreprocessor begins searches for the file to be included.
If the file name is enclosed in quotes, the preprocessorstarts searches in the same directory as the file beingcompiled for the file to be included (and may search otherlocations, too).
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
5/39
#include Preprocessor Directive 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 isperformed in an implementation-dependent manner,normally through predesignated compiler andsystem directories.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
6/39
#include Preprocessor Directive The #include directive is used to include standard
library headers such as stdio.h and stdlib.h(see Fig. 5.6) and with programs consisting ofseveral source files that are to be compiled together.
A header containing declarations common to theseparate program files is often created and includedin the file.
Examples of such declarations are structure andunion declarations, enumerations and functionprototypes.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
7/39
#define Preprocessor Directive:Symbolic Constants
The #define directive creates symbolic
constantsconstants represented as symbolsandmacros operations defined as symbols.
The #define directive format is #define#define#define#define identifier identifier identifier identifier replacement replacement replacement replacement- -- -text text text text
When this line appears in a file, all subsequentoccurrences of identifier that do not appear in string
literals will be replaced by replacement-textautomatically before the program is compiled.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
8/39
#define Preprocessor Directive: SymbolicConstants (Cont.) For example,
#define#define#define#define PI 3.14159PI 3.14159PI 3.14159PI 3.14159
replaces all subsequent occurrences of the symbolicconstant PI with the numeric constant 3.14159 .
Symbolic constants enable you to create a name fora constant and use the name throughout the program.
If the constant needs to be modified throughout theprogram, it can be modified once in the #definedirective.
When the program is recompiled, all occurrences ofthe constant in the program will be modifiedaccordingly.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
9/39
8/13/2019 BTCS 1223_Chap8_Preprocessor
10/39
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
11/39
#define Preprocessor Directive: Macros A macro is an identifier defined in a #define
preprocessor directive. As with symbolic constants, the macro-identifier is
replaced in the program with the replacement-text beforethe 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 substitutedin the replacement text, then the macro is expanded i.e.,the replacement-text replaces the identifier and argumentlist in the program.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
12/39
#define Preprocessor Directive: Macros(Cont.)
[ Note: A symbolic constant is a type of macro.]
Consider the following macro definition with oneargument for the area of a circle:
#define#define#define#define CIRC ! R!CIRC ! R!CIRC ! R!CIRC ! R! $ % & $ $$ % & $ $$ % & $ $$ % & $ $ PIPIPIPI & ' $ % & '& ' $ % & '& ' $ % & '& ' $ % & '
$ % & &$ % & &$ % & &$ % & & Wherever CIRC ! R! $(& appears in the file,
the value of ( is substituted for %in the
replacement-text, the symbolic constant PI isreplaced by its value (defined previously) and themacro is expanded in the program.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
13/39
#define Preprocessor Directive: Macros(Cont.)
For example, the statement a)ea = CIRC ! R!CIRC ! R!CIRC ! R!CIRC ! R! $$$$ 4444 &*&*&*&*
is expanded to a)ea = $ $ 3.141593.141593.141593.14159 & ' $& ' $& ' $& ' $ 4444 & ' $& ' $& ' $& ' $ 4444 & &*& &*& &*& &*
and the value of the expression is evaluated andassigned to variable a)ea .
The parentheses around each %in the replacementtext force the proper order of evaluation when themacro argument is an expression.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
14/39
8/13/2019 BTCS 1223_Chap8_Preprocessor
15/39
#define Preprocessor Directive: Macros(Cont.)
If the parentheses are omitted, the macro expansion
is a)ea = 3.141593.141593.141593.14159 ' c + ,,, , ' c + ,,, , *
which evaluates incorrectly as
a)ea = $ 3.141593.141593.141593.14159 ' c & + $ ,,, , ' c & + ,,, , *because of the rules of operator precedence.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
16/39
#define Preprocessor Directive: Macros(Cont.)
Macro CIRC ! R! could be defined as a
function. Function ci)cle )ea
doubledoubledoubledouble ci)cle )ea$ci)cle )ea$ci)cle )ea$ci)cle )ea$ doubledoubledoubledouble % &% &% &% &----
)etu)n)etu)n)etu)n)etu)n 3.141593.141593.141593.14159 ' % ' %*' % ' %*' % ' %*' % ' %*
performs the same calculation as macro
CIRC ! R! , but the overhead of a function callis associated with function ci)cle )ea .
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
17/39
#define Preprocessor Directive: Macros(Cont.)
The advantages of macro CIRC ! R! are that
macros insert code directly in the programavoiding function call overheadand the programremains readable because the CIRC ! R!
calculation is defined separately and namedmeaningfully. A disadvantage is that its argument is evaluated
twice.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
18/39
8/13/2019 BTCS 1223_Chap8_Preprocessor
19/39
#define Preprocessor Directive: Macros(Cont.) The following is a macro definition with two arguments
for the area of a rectangle: #define#define#define#define R!C/ 0 ! R!R!C/ 0 ! R!R!C/ 0 ! R!R!C/ 0 ! R! $ %2 ( & $ $ % & ' $ ( & & Wherever R!C/ 0 ! R! $%2 (& appears in the
program, the values of %and ( are substituted in themacro replacement text and the macro is expanded inplace of the macro name.
For example, the statement )ect )ea = R!C/ 0 ! R!R!C/ 0 ! R!R!C/ 0 ! R!R!C/ 0 ! R! $ a + 44442 b + &*
is expanded to )ect )ea = $ $ a + 4444 & ' $ b + & &*
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
20/39
#define Preprocessor Directive: Macros(Cont.) The value of the expression is evaluated and
assigned to variable )ect )ea . The replacement text for a macro or symbolicconstant is normally any text on the line after theidentifier in the #define directive.
If the replacement text for a macro or symbolicconstant is longer than the remainder of the line, abackslash (\ ) must be placed at the end of the line,indicating that the replacement text continues on thenext line.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
21/39
#define Preprocessor Directive: Macros(Cont.) 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 , oruntil the end of the file. Once undefined, a name can be redefined with
#define . Functions in the standard library sometimes are
defined as macros based on other library functions.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
22/39
#define Preprocessor Directive: Macros(Cont.) A macro commonly defined in the stdio.h header is
#define#define#define#define etcha)$& etc$ stdin &etcha)$& etc$ stdin &etcha)$& etc$ stdin &etcha)$& etc$ stdin & The macro definition of etcha) uses function etc
to get one character from the standard input stream.
Function utcha) of the stdio.h header and thecharacter handling functions of the ct( e.h headeroften are implemented as macros as well.
Expressions with side effects (i.e., variable values aremodified) should not be passed to a macro becausemacro arguments may be evaluated more than once.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
23/39
Conditional Compilation Conditional compilation enables you to control the
execution of preprocessor directives and thecompilation of program code. Each of the conditional preprocessor directives
evaluates a constant integer expression. Cast expressions, si6eof expressions and
enumeration constants cannot be evaluated inpreprocessor directives.
The conditional preprocessor construct is much likethe if selection statement.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
24/39
Conditional Compilation (Cont.) Consider the following preprocessor code:
#if#if#if#if 7defined$7defined$7defined$7defined$ 8 C:0;/ 0/8 C:0;/ 0/8 C:0;/ 0/8 C:0;/ 0/ &&&define#define#define#define 8 C:0;/ 0/8 C:0;/ 0/8 C:0;/ 0/8 C:0;/ 0/
#endif#endif#endif#endif
These directives determine if 8 C:0;/ 0/ is defined.
The expression defined$ 8 C:0;/ 0/& evaluatesto 1 if 8 C:0;/ 0/ is defined; otherwise.
If the result is , 7defined$8 C:0;/ 0/& evaluates
to 1 and 8 C:0;/ 0/ is defined. Otherwise, the #define directive is skipped.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
25/39
Conditional Compilation (Cont.) Every #if construct ends with #endif .
Directives #ifdef and #ifndef are shorthand for #ifdefined$ name & and #if 7defined$ name &. A multiple-part conditional preprocessor construct may be
tested by using the #elif (the equivalent of else if inan if statement) and the #else (the equivalent of elsein an if statement) directives.
These directives are frequently used to prevent header filesfrom being included multiple times in the same source file.
We use this technique extensively in the C++ part of thisbook.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
26/39
Conditional Compilation (Cont.) During program development, it is often helpful to
comment out portions of code to prevent it frombeing compiled.
If the code contains comments, ' and ' cannot beused to accomplish this task.
Instead, you can use the following preprocessorconstruct: #if#if#if#if
code prevented from compiling code prevented from compiling code prevented from compiling code prevented from compiling #endif #endif #endif #endif
To enable the code to be compiled, replace the inthe preceding construct with 1 .
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
27/39
Conditional Compilation (Cont.) Conditional compilation is commonly used as a debugging
aid. Many C implementations provide debuggers , whichprovide much more powerful features than conditionalcompilation.
If a debugger is not available, )intf statements areoften used to print variable values and to confirm the flowof control.
These )intf statements can be enclosed in conditionalpreprocessor directives so the statements are onlycompiled while the debugging process is not completed.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
28/39
Conditional Compilation (Cont.) For example,
#ifdef#ifdef#ifdef#ifdef !?@!?@!?@!?@)intf$)intf$)intf$)intf$ "Aa)iable % = Bd"Aa)iable % = Bd"Aa)iable % = Bd"Aa)iable % = Bd n"n"n"n" 2 % &*2 % &*2 % &*2 % &*#endif#endif#endif#endif
causes a )intf statement to be compiled in theprogram if the symbolic constant !?@ has beendefined ( #define !?@ ) before directive#ifdef !?@ .
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
29/39
Conditional Compilation (Cont.) When debugging is completed, the #define
directive is removed from the source file (orcommented out) and the )intf statementsinserted for debugging purposes are ignored during
compilation. In larger programs, it may be desirable to define
several different symbolic constants that control the
conditional compilation in separate sections of thesource file.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
30/39
#e))o) and # )a ma PreprocessorDirectives The #error directive
#e))o)#e))o)#e))o)#e))o) tokens tokens tokens tokens
prints an implementation-dependent message including thetokens specified in the directive.
The tokens are sequences of characters separated byspaces.
For example, #e))o)#e))o)#e))o)#e))o) 1111 DDDD :ut of )an e e))o):ut of )an e e))o):ut of )an e e))o):ut of )an e e))o)
contains 6 tokens. When a #e))o) directive is processed on some systems,
the tokens in the directive are displayed as an errormessage, preprocessing stops and the program does notcompile.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
31/39
#e))o) and # )a ma PreprocessorDirectives (Cont.) The #pragma directive
# )a ma# )a ma# )a ma# )a ma tokens tokens tokens tokens causes an implementation-defined action.
A pragma not recognized by the implementation is
ignored.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
32/39
Line Numbers The #line preprocessor directive causes the
subsequent source code lines to be renumberedstarting with the specified constant integer value. The directive
#line#line#line#line 1111starts line numbering from 1 beginning with thenext source code line.
A file name can be included in the #line directive.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
33/39
Line Numbers (Cont.) The directive
#line#line#line#line 1 "file1.c"1 "file1.c"1 "file1.c"1 "file1.c"
indicates that lines are numbered from 1beginning with the next source code line and that thename of the file for the purpose of any compilermessages is "file1.c" .
The directive normally is used to help make themessages produced by syntax errors and compiler
warnings more meaningful. The line numbers do not appear in the source file.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
34/39
Predefined Symbolic Constants Standard C provides predefined symbolic constants,
several of which are shown in Fig. 13.1. The identifiers for each of the predefined symbolic
constants begin and end with two underscores.
These identifiers and the defined identifier (usedin Section 13.5) cannot be used in #define or#undef directives.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
35/39
1992-2010 by Pearson Education,Inc. All Rights Reserved.
macro value
__LINE__Integer value re resenting the current line in the source code !ile"eing com iled#
__$ILE__% string literal containing the resumed name o! the source !ile
"eing com iled#
__&%'E__% string literal in the !orm (Mmm dd ))))( containing the date in*hich the com ilation rocess "egan#
__'IME__% string literal in the !orm (hh:mm:ss( containing the time at
*hich the com ilation rocess "egan#
__c lus lus
%n integer value# %ll +,, com ilers have this constant de!ined tosome value# I! the com iler is !ull) com liant *ith the +,,standard its value is e-ual or greater than 1.. 11L de ending on
the version o! the standard the) com l)#
8/13/2019 BTCS 1223_Chap8_Preprocessor
36/39
Assertions The assert macrodefined in the
headertests the value of an expression . If the value of the expression is false ( ), asse)t
prints an error message and calls function abort(of the general utilities library ) toterminate program execution.
This is a useful debugging tool for testing if avariable has a correct value.
For example, suppose variable %should never belarger than 1 in a program.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
37/39
Assertions (Cont.) An assertion may be used to test the value of %and
print an error message if the value of %is incorrect. The statement would be
asse)t$ %
8/13/2019 BTCS 1223_Chap8_Preprocessor
38/39
Assertions (Cont.) You may then concentrate on this area of the code to
find the error. If the symbolic constant 0 !?@ is defined,
subsequent assertions will be ignored.
Thus, when assertions are no longer needed, the line #define#define#define#define 0 !?@0 !?@0 !?@0 !?@
is inserted in the program file rather than deleting
each assertion manually.
1992-2010 by Pearson Education,Inc. All Rights Reserved.
8/13/2019 BTCS 1223_Chap8_Preprocessor
39/39
1992-2010 by Pearson Education,Inc. All Rights Reserved.
Recommended