C Preprocessor

So Today we are going to discuss about C Preprocessor.

So first we discuss about What is Preprocessor?
The C preprocessor is exactly what its name implies , It is a program that processes our source program before it is passed to the compiler.




So now we are going to discuss about Features of C Preprocessor
The preprocessor offers several features called preprocessor directives. Each of these preprocessor directives begin with a #(hash) symbol. The directives can be placed anywhere in a program but
are most often placed at the beginning of a program.

We will learn the following preprocessor directives here:
(a) Macro expansion

So, In this blog we are going to discuss about Macro Expansion only and in next blog we will discuss about rest of the others.

Macro Expansion

So, macro is a fragment of code which has been given a name. Whenever the name is used, it is replaced by the contents of the macro.

Have a look at the following program.
#define PI 3.1415
main( )
{
  float r = 6.25 ;
  float area ;
  area = PI * r * r ;
  printf ( "\nArea of circle = %f", area ) ;
}

In this program we had defined PI before main( ) through the statement,
#define PI 3.1415
This statement is called ‘macro definition’ or more commonly, just a ‘macro’.

So,Now we discuss How it is done? 

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 find one, it replaces the macro template with the appropriate macro expansion. Only after this procedure has been completed is the program handed over to the compiler.
 
So Now a Question arises that why do we use macros?
There is a more important reason for using macro definition than mere readability. 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.
In short, it is nice to know that you would be able to change values of a constant at all the places in the program by just making a change in the #define directive.

Following three examples show places where a #define directive is popularly used by C programmers.
• 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" ) ;
 }

• A #define directive could be used even to replace a condition, as shown below.

#define AND &&
#define RANGE ( a > 25 AND a < 50 )
main( )
{
  int a = 30 ;
  if ( RANGE )
      printf ( "within range" ) ;
  else
      printf ( "out of range" ) ;
}

• A #define directive could be used to replace even an entire C statement. This is shown below.

#define FOUND printf ( "The Yankee Doodle Virus" ) ;
main( )
{
   char signature ;
   if ( signature == 'Y' )
   FOUND
   else
   printf ( "Safe... as yet !" ) ;
}

Macros with Arguments
The macros that we have used so far are called simple macros. Macros can have arguments, just as functions can. Here is an example that illustrates this fact.

#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 ) ;
}

Here’s the output of the program...

Area of circle = 122.656250
Area of circle = 19.625000

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 this:

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 ) ;
 }

Here are some important points to remember while writing macros with arguments:
(a) 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.
(b) 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.
What went wrong? The macro was expanded into
      j = 64 / 4 * 4 ;
which yielded 64.
(c) Macros can be split into multiple lines, with a ‘\’ (back slash) present at the end of each line. Following program shows how we can define and use multiple line macros.
      
#define HLINE for( i = 0 ; i < 79 ; i++ ) \
                      printf ( "%c", 196 ) ;
#define VLINE( X, Y ) {\
                               gotoxy ( X, Y ) ; \
                               printf ( "%c", 179 ) ; \
                                      }
       main( )
      {
         int i, y ;
         clrscr( ) ;
         gotoxy ( 1, 12 ) ;
         HLINE
         for ( y = 1 ; y < 25 ; y++ )  
         VLINE ( 39, y ) ;
       }

This program draws a vertical and a horizontal line in the center of the screen.

So as I told above we will discuss the rest of the preprocessor directives in next blog.


Comments

Post a Comment