0% found this document useful (0 votes)
16 views52 pages

The C Preprocessor by Satbir Singh

The C preprocessor is a program that processes source code before it is compiled, utilizing directives that begin with a # symbol to perform tasks like macro expansion, file inclusion, and conditional compilation. It transforms the source code by replacing macros with their defined values, making the code easier to read and maintain. The document also discusses the differences between macros and functions, emphasizing that macros are expanded literally while functions involve control passing.

Uploaded by

nickyhooda35
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views52 pages

The C Preprocessor by Satbir Singh

The C preprocessor is a program that processes source code before it is compiled, utilizing directives that begin with a # symbol to perform tasks like macro expansion, file inclusion, and conditional compilation. It transforms the source code by replacing macros with their defined values, making the code easier to read and maintain. The document also discusses the differences between macros and functions, emphasizing that macros are expanded literally while functions involve control passing.

Uploaded by

nickyhooda35
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 52

The C Preprocessor

Satbir Singh
Assistant Professor
Department of Mathematics
Govt. College for Girls, Palwal, Kurukshetra, Haryana
The C preprocessor

• It is a program that processes our


source program before it is passed to
the compiler.

Let Us C By Y Kanetkar
The C preprocessor

• It is a program that processes our source


program before it is passed to the compiler.
• Preprocessor commands (often known as
directives) form what can almost be
considered a language within C language.

Let Us C By Y Kanetkar
• There are several steps involved from the
stage of writing a C program to the stage of
getting it executed.

Let Us C By Y Kanetkar
• There are several steps involved from the
stage of writing a C program to the stage of
getting it executed.

• The Figure on next slide shows these


different steps along with the files created during
each stage. You can observe from the figure
that our program passes through several
processors before it is ready to be
executed.

Let Us C By Y Kanetkar
Note that if the source code
is stored in a file PR1.C

Let Us C By Y Kanetkar
Note that if the source code
is stored in a file PR1.C

The expanded source code


gets stored in a file PR1.I.

Let Us C By Y Kanetkar
Note that if the source code
is stored in a file PR1.C

The expanded source code


gets stored in a file PR1.I.
When this expanded source
code is compiled the object
code gets stored in
PR1.OBJ.

Let Us C By Y Kanetkar
Note that if the source code
is stored in a file PR1.C

The expanded source code


gets stored in a file PR1.I.
When this expanded source
code is compiled the object
code gets stored in
PR1.OBJ.
When this object code is
linked with the object code
of library functions the
resultant executable code
gets stored in PR1.EXE.
Let Us C By Y Kanetkar
• The input and output to each of these
processors is in the following Figure

Let Us C By Y Kanetkar
Some Important things to remember:

Let Us C By Y Kanetkar
Some Important things to remember:

 The preprocessor offers several features called


preprocessor directives.

Let Us C By Y Kanetkar
Some Important things to remember:

 The preprocessor offers several features called


preprocessor directives.

 Each of these preprocessor directives begin with


a # symbol.

Let Us C By Y Kanetkar
Some Important things to remember:

 The preprocessor offers several features called


preprocessor directives.

 Each of these preprocessor directives begin with


a # symbol.

 The directives can be placed anywhere in a


program but are most often placed at the
beginning of a program, before the first function
definition.
Let Us C By Y Kanetkar
We would learn the following preprocessor
directives here:
(a) Macro expansion
(b) File inclusion
(c) Conditional Compilation
(d) Miscellaneous directives

Let us start with Macro Expansion

Let Us C By Y Kanetkar
#define UPPER 25
main( )
{
int i ;
for ( i = 1 ; i <= UPPER ; i++ )
printf ( "\n %d", i ) ;
}

Let Us C By Y Kanetkar
#define UPPER 25
main( )
{
int i ;
for ( i = 1 ; i <= UPPER ; i++ )
printf ( "\n %d", i ) ;
}

In this program instead of writing 25 in the


for loop we are writing it in the form of
UPPER, which has already been defined
before main( ) through the statement,

#define UPPER 25
Let Us C By Y Kanetkar
 This statement is called ‘macro definition’ or
more commonly, just a ‘macro’.

Let Us C By Y Kanetkar
 This statement is called ‘macro definition’ or
more commonly, just a ‘macro’.

 During preprocessing, the preprocessor replaces


every occurrence of UPPER in the program
with 25.

Let Us C By Y Kanetkar
 This statement is called ‘macro definition’ or
more commonly, just a ‘macro’.

 During preprocessing, the preprocessor replaces


every occurrence of UPPER in the program
with 25.

Let us consider another example:


#define PI 3.1415
main( )
{
float r = 6.25 ;
float area ;
area = PI * r * r ;
printf ( "\nArea of circle = %f",
area ) ;
} Let Us C By Y Kanetkar
UPPER and PI in the above programs are often called
‘macro templates’, whereas, 25 and 3.1415 are called
their corresponding ‘macro expansions’.

Let Us C By Y Kanetkar
UPPER and PI in the above programs are often called
‘macro templates’, whereas, 25 and 3.1415 are called
their corresponding ‘macro expansions’.

When we compile the program, before the source code


passes to the compiler, it is examined by the C
preprocessor for any macro definitions.

Let Us C By Y Kanetkar
UPPER and PI in the above programs are often called
‘macro templates’, whereas, 25 and 3.1415 are called
their corresponding ‘macro expansions’.

When we compile the program, before the source code


passes to the compiler, it is examined by the C
preprocessor for any macro definitions.

When it sees the #define directive, it goes through the


entire program in search of the macro templates;

Let Us C By Y Kanetkar
UPPER and PI in the above programs are often called
‘macro templates’, whereas, 25 and 3.1415 are called
their corresponding ‘macro expansions’.

When we compile the program, before the source code


passes to the compiler, it is examined by the C
preprocessor for any macro definitions.

When it sees the #define directive, it goes through the


entire program in search of the macro templates;

wherever it finds one, it replaces the macro template with


the appropriate macro expansion.

Let Us C By Y Kanetkar
UPPER and PI in the above programs are often called
‘macro templates’, whereas, 25 and 3.1415 are called
their corresponding ‘macro expansions’.

When we compile the program, before the source code


passes to the compiler, it is examined by the C
preprocessor for any macro definitions.

When it sees the #define directive, it goes through the


entire program in search of the macro templates;

wherever it finds one, it replaces the macro template with


the appropriate macro expansion.

Only after this procedure has been completed , the


program handed over to the compiler.

Let Us C By Y Kanetkar
In C programming it is customary to use capital letters
for macro template.

Note that a macro template and its macro expansion are


separated by blanks or tabs.

A space between # and define is optional.

Remember that a macro definition is never to be


terminated by a semicolon.

Let Us C By Y Kanetkar
Note that a macro template and its macro expansion are
separated by blanks or tabs. A space between # and
define is optional. Remember that a macro definition is
never to be terminated by a semicolon.

Why we use #define in the above programs? What


have we gained by substituting PI for 3.1415 in our
program?

Let Us C By Y Kanetkar
Note that a macro template and its macro expansion are
separated by blanks or tabs. A space between # and
define is optional. Remember that a macro definition is
never to be terminated by a semicolon.

Why we use #define in the above programs? What


have we gained by substituting PI for 3.1415 in our
program?

Probably, we have made the program easier to read.


Even though 3.1415 is such a common constant that it
is easily recognizable, there are many instances where a
constant doesn’t reveal its purpose so readily.

Let Us C By Y Kanetkar
For example, if the phrase “\x1B[2J” causes the screen to
clear. But which would you find easier to understand in the
middle of your program “\x1B[2J” or “CLEARSCREEN”?
Thus, we would use the macro definition

#define CLEARSCREEN "\x1B[2J"

Let Us C By Y Kanetkar
For example, if the phrase “\x1B[2J” causes the screen to
clear. But which would you find easier to understand in the
middle of your program “\x1B[2J” or “CLEARSCREEN”?
Thus, we would use the macro definition

#define CLEARSCREEN "\x1B[2J"

There is perhaps a more important reason for


using macro definition than mere readability.

Let Us C By Y Kanetkar
Suppose a constant like 3.1415 appears many times in your
program. This value may have to be changed some day to
3.141592.

Let Us C By Y Kanetkar
Suppose a constant like 3.1415 appears many times in your
program. This value may have to be changed some day to
3.141592.

Ordinarily, you would need to go through the program and


manually change each occurrence of the constant.

Let Us C By Y Kanetkar
Suppose a constant like 3.1415 appears many times in your
program. This value may have to be changed some day to
3.141592.

Ordinarily, you would need to go through the program and


manually change each occurrence of the constant.

However, if you have defined PI in a #define directive, you


only need to make one change, in the #define directive
itself:
#define PI 3.141592

Let Us C By Y Kanetkar
Suppose a constant like 3.1415 appears many times in your
program. This value may have to be changed some day to
3.141592.

Ordinarily, you would need to go through the program and


manually change each occurrence of the constant.

However, if you have defined PI in a #define directive, you


only need to make one change, in the #define directive
itself:
#define PI 3.141592

Beyond this the change will be made automatically to all


occurrences of PI before the beginning of compilation.

Let Us C By Y Kanetkar
A #define directive is many a times used to define operators as
shown below.

Let Us C By Y Kanetkar
A #define directive is many a times used to define operators as
shown below.

#define AND &&


#define OR ||

main( )
{
int f = 1, x = 4, y = 90 ;

if ( ( f < 5 ) AND ( x <= 20 OR y <= 45 ) )


printf ( "\nYour PC will always work fine..." ) ;
else
printf ( "\nIn front of the maintenance man" ) ;
}

Let Us C By Y Kanetkar
A #define directive could be used even to replace a
condition, as shown below.

Let Us C By Y Kanetkar
A #define directive could be used even to replace a
condition, as shown below.

#define AND &&


#define ARANGE ( a > 25 AND a < 50 )
main( )
{
int a = 30 ;

if ( ARANGE )
printf ( "within range" ) ;
else
printf ( "out of range" ) ;
}

Let Us C By Y Kanetkar
A #define directive could be used to replace even an entire C
statement.

Let Us C By Y Kanetkar
A #define directive could be used to replace even an entire C
statement.

#define FOUND printf ( "The Yankee Doodle Virus" ) ;


main( )
{
char signature ;

if ( signature == 'Y' )
FOUND
else
printf ( "Safe... as yet !" ) ;
}

Let Us C By Y Kanetkar
Macros with Arguments
The macros that we have used so far are called simple
macros. Macros can have arguments, just as functions can.

#define AREA(x) ( 3.14 * x * x )


main( )
{
float r1 = 6.25, r2 = 2.5, a;
a = AREA ( r1 );
printf ( "\nArea of circle = %f", a );
a = AREA ( r2 );
printf ( "\nArea of circle = %f", a );
}

Let Us C By Y Kanetkar
In this program wherever the preprocessor finds the phrase
AREA(x) it expands it into the statement ( 3.14 * x * x ).

 However, that’s not all that it does. The x in the


macro template AREA(x) is an argument that matches
the x in the macro expansion ( 3.14 * x * x ). The
statement AREA(r1) in the program causes the variable r1
to be substituted for x.

 Thus the statement AREA(r1) is equivalent to:


( 3.14 * r1 * r1 )

 After the above source code has passed through the


preprocessor, what the compiler gets to work on will
be in red boundary as on next slide:

Let Us C By Y Kanetkar
#define AREA(x) ( 3.14 * x * x )
main( )
{
float r1 = 6.25, r2 = 2.5, a;
a = AREA ( r1 );
printf ( "\nArea of circle = %f", a );
a = AREA ( r2 );
printf ( "\nArea of circle = %f", a );
}

main( )
{
float r1 = 6.25, r2 = 2.5, a ;
a = 3.14 * r1 *r1 ;
printf ( "Area of circle = %f\n", a ) ;
a = 3.14 *r2 * r2 ;
printf ( "Area of circle = %f", a ) ;
} Let Us C By Y Kanetkar
Here are some important points to remember while writing
macros with arguments:

Be careful not to leave a blank between the macro template and


its argument while defining the macro.

For example, there should be no blank between AREA and (x)


in the definition, #define AREA(x) ( 3.14 * x * x )
If we were to write AREA (x) instead of AREA(x), the (x)
would become a part of macro expansion, which we certainly
don’t want.

What would happen is, the template would be expanded to


( r1 ) ( 3.14 * r1 * r1 )
which won’t run. Not at all what we wanted.
Let Us C By Y Kanetkar
The entire macro expansion should be enclosed within parentheses.

Here is an example of what would happen if we fail to enclose


the macro expansion within parentheses.

#define SQUARE(n) n * n
main( )
{
int j ;
j = 64 / SQUARE ( 4 ) ;
printf ( "j = %d", j ) ;
}
The output of the above program would be:
j = 64
whereas, what we expected was j = 4.

Let Us C By Y Kanetkar
What went wrong? The macro was expanded into
j = 64 / 4 * 4 ;
which yielded 64.

Macros can be split into multiple lines, with a ‘\’ (back


slash) present at the end of each line.

If for any reason you are unable to debug a macro then you
should view the expanded code of the program to see how the
macros are getting expanded.

Let Us C By Y Kanetkar
If your source code is present in the file PR1.C then the
expanded source code would be stored in PR1.I.

Let Us C By Y Kanetkar
Macros versus Functions
In the above example a macro was used to calculate the area of the
circle.

As we know, even a function can be written to calculate the area of


the circle. Though macro calls are ‘like’ function calls, they are not
really the same things. Then what is the difference between the two?

In a macro call the preprocessor replaces the macro template with


its macro expansion, in a stupid, unthinking, literal way.

As against this, in a function call the control is passed to a function


along with certain arguments, some calculations are performed in
the function and a useful value is returned back from the function.

Let Us C By Y Kanetkar
This brings us to a question: when is it best to use macros with
arguments and when is it better to use a function?

Usually macros make the program run faster but increase the
program size, whereas functions make the program smaller
and compact.

If we use a macro hundred times in a program, the macro


expansion goes into our source code at hundred different
places, thus increasing the program size.

Let Us C By Y Kanetkar
On the other hand, if a function is used, then even if it is
called from hundred different places in the program, it
would take the same amount of space in the program.

But passing arguments to a function and getting back the


returned value does take time and would therefore slow down
the program.

This gets avoided with macros since they have already been
expanded and placed in the source code before compilation.

Let Us C By Y Kanetkar
Moral of the story is—if the macro is simple and sweet like in
our examples, it makes nice shorthand and avoids the
overheads associated with function calls.

On the other hand, if we have a fairly large macro and it is


used fairly often, perhaps we ought to replace it with a
function.

Let Us C By Y Kanetkar
Thank You

Let Us C By Y Kanetkar

You might also like