The C – Preprocessor
The preprocessor
is a program that processes the source code before it passes through the
compiler. It operates under the control of preprocessor command line or
directives. Preprossor directives are placed in the source program before the
main line. Before the source code passes through the compiler, it is examined
by preprocessor. After taking appropriate actions as directed by preprocessor,
the source program is handed over to the compiler.
The
syntax of preprocessor directives begin with the symbol # and donot require semi colon (;) at the end. The preprocessor directives can
be divided into three categories.
- Macro substitution
- File Inclusion
- Compiler control Directives
1. Macro Substitution:
In macro substitution, an IDENTIFIER is replaced by pre-defined string. The
preprocessor accomplishes this job under the direction of #define
directives which is called macro. The syntax for macro definition is:
#define IDENTIFIER string
If
this line is included at the beginning of the program, preprocessor replaces
IDENTIFIER in source code by string defined in macro. The IDENTIFIER must be C
valid name.
There are three
different forms of macro substitutions:
a.
Simple macro substitution
b.
Arguemented
macro substitution
c.
Nested macro substitution
èA simple macro:
A
simple macro is generally used to
define symbolic constants.
example:
#define
PI 3.14159
#define TRUE 1
#define CITY “Kathmandu ”
#define TWO_PI 2*(22/7)
#define BLANK_LINE printf(“\n”);
#define INCREMENT ++
#define START
{
#define END
}
etc.
The Uppercase
letter for IDENTIFIER is conventions for defining Constants.
è Arguemented
macro :
We can define complex macro
with arguments. The syntax is
#define
IDENTIFIER(a1,a2,…..,an)
string
ü
There is no space between IDENTIFIER and parenthesis .
ü
a1,a2,….,an are macro formal
parameters.
ü
When a
macro is called , the preprocessor substitutes the string, replacing the formal
parameters with actual parameters( passed when calling macro )
Example:
#define SQUARE(x) ((x)*(x))
#define SQUARE(x) ((x)*(x))
#define CUBE (x) ((x)*(x)*(x))
We can call these macro in our source program
as
Area =
PI*SQUARE(radius);
Which is equivalent to :
Area = PI*((radius)*(radius)); /*substitution of macro */
Other examples of arguemented
macro:
#define MAX(a,b) (((a)>(b))? (a): (b))
#define MIN(a,b) (((a)<(b))?
(a) : (b))
#define MODVAL(x) (((x)>0)
? (x) : (-(x)))
#define RECIPROCAL(x) (1.0/(x)) etc.
è Nesting macro:
We can use one pre-defined
macro to define new macro. This is called nesting of macro definition.
Example:
#define PI 3.14159
#define PI 3.14159
#define TWO_PI 2*PI
#define SQUARE(x) ((x)*(x))
#define CUBE (x) ((x)*SQUARE(x))
#define SIX_POWER(x) ((CUBE (x))*(CUBE(x)))
ü
Given the definition of macro MAX (a,b) , We can use nested call of macro to fine
maximum of three numbers a,b,c as:
- To define multiple lines we can use \ character at the end of each line:
Undifining
a Macro:
A defined macro can be undefined , using the
statement:
#undef IDENTIFIER
it is useful when to restrict the
definition only to a particular part of the program.
2. File
inclusion directives: (#include
directives)
A
file which contains the pre-defined macros and functions can be included in our
source program using #include directive. If we include pre-written file in our source program we
need not to rewrite the functions and macro which are defined in that file.
The syntax for file inclusion
directive is :
#include<filename> or #include “filename”
è When
#include<filename> is used, the file inside < > is searched in the standard directory and included in the
source program where it is written. If file is not find an error is reported.
è When #include
“filename” is used , the file inside “
” is searched first in the
current directory and then standard directory
included in the source program where it is written. If file is not find
an error is reported.
A simple example of file inclusion:
Consider a file named test.c which includes the definition of
functions for square and cube and macro to find the maximum of two numbers ,
and constant PI.
/* test.c */
#define PI
3.14
#define MAX (x,y) ( ( (x) > (y) ) ? (x) : (y) )
int square(int x) /*square
function */
{
return x*x;
}
int cube(int x) /*cube function */
{
return (x*x*x);
}
Now we have to write a program
that uses functions and macros defined in
test.c. the source program is as:
/*source.c */
#include<stdio.h>
#include “test.c”
void main()
{
int x =10, y=20;
printf(“\nThe square of %d is %d” , x,
square(x));
printf(“\nThe cube of %d is %d “, x,
cube(x));
printf(“\n The larger no is %d.”, MAX(a,b));
}
when we run the source file
source.c the output will be
The square of 10 is 100
The cube of 10 is 1000
The larger no is 20.
3. Compiler
control directives(Conditional Compilation)
Conditional
compilation enables the programmer to control the execution of preprocessor
directive and the compilation of the program code. Each of the conditional
preprocessor directive evaluates a conatant integer expression.
The conditional preprocessor directive
construct is similar to if-else construct. The conditional compilation can be
done using #if, #elif ,#else, #ifdef
,#ifndef.
Examples:
#if
defined(NULL)
#undef
NULL
#endif
This can be equivalently defined as :
#ifdef NULL
#ifdef NULL
#undef
NULL
#endif
This conditional directives search for the definition of NULL in the
current header file and source file if it is defined then it is undefined.
Similarly:
#if !defined(NULL)
#define NULL 0
#endif
or equivalently,
#ifndef
NULL
#define
NULL 0
#endif
This conditional directives
search for the definition of NULL in the current header file and source file if
it is not defined then it is defined to 0.In the above directives, if line
evaluates the constant integer expression. If expression is non-zero,
subsequent lines until #endif are included.
For multiple selection of lines
to include, #elif, #else can be used as else if and else in selection
structures. Suppose there is different
versions of header file for different systems. To decide which version of a
header file to include, we can write preprocessor directive as:
#if SYSTEM ==
SYSV
#define HDR “sysv.h”
#elif SYSTEM ==
BSD
#define HDR “bsc.h”
#elif SYSTEM ==
MSDOS
#define
HDR “msdos.h”
#else
#define
HDR “default.h”
#endif
#include HDR
Some Pre defined macros
1. __DATE__ A string containing the current
date of the form “Mmm dd yyyy”
2. __TIME__ A string containing the current
time of the form “hh:mm:ss”
3. __LINE __ The line number of the current
source code line
4. __FILE __ The file name of the current
source file
5.__STDC__ If
implementation follows ANSI
standard of C then value is non zero.
Try the
following Code in your program:
printf(“\n__DATE__
= %s”, __DATE__);
printf(“\n__TIME__
= %s”, __TIME__);
printf(“\n__LINE __ = %s”,__LINE __);
printf(“\n__FILE __ =
%s”, __FILE __);
printf(“\n__STDC__
= %s”,__STDC__);
No comments:
Post a Comment