Logo 
Search:

C Programming Articles

Submit Article
Home » Articles » C Programming » BeginnersRSS Feeds

Preprocessor

Posted By: Ella Brown     Category: C Programming     Views: 17743

This article explains about preprocessor, Categories of Preprocessor Directives, Macro Substitution, Simple Macro Sub to Define Constants, Simple Macro Sub for Expressions, Nesting of Macros etc.

What Is Preprocessor?

  • Easy to read, easy to modify, more portable with more efficiency are imp issues
  • The preprocessor processes the program before it passes to the compiler
  • It operates under the control of directives
  • They have different syntax rules!
  • # Initially and no semicolon at the end!

Categories of Preprocessor Directives

  • Macro substitution directives relates to replacing an identifier with predefined string or one or more tokens
  • File inclusion directives relates to include a source file to current program
  • Compiler control directives are for developing a single comprehensive program to suit different situations

Macro Substitution

  • Is done under the control of #define 
  • It takes the general form #define id string
  • Id must be any valid C name and the string may be any text
  • Three diff forms of macro substitution are
    • Simple macro substitution
    • Argument macro substitution
    • Nested macro substitution


Simple Macro Sub to Define Constants


Replacement starts from the line of definition
Macro inside a string does not get replaced

Simple Macro Sub for Expressions

#define    AREA        5 * 12.46
#define     SIZE          sizeof(int) * 4
#define     TWO-PI     2.0  * 3.1415596
#define      D               (45 – 22)
#define      A               (78 + 32)
  • Expression like D/A should be (45-22)/(78 +32) and not 45 – 32/78 +32
  • It performs a literal text sub so no ; is required

Simple Macro Sub for Creating C Sentences

  • #define      TEST    if (x>y)
  • #define       AND
  • #define      PRINT  printf(“Very Good\n”);
  • We can now write TEST AND PRINT
  • That will become
  • if  (x>y) printf (“Very Good\n”);

Simple Macro Sub for Replacing Tokens

#define     EQALS                ==
#define     AND                    &&
#define     OR                         ||
#define     NOT-EQUAL       !=
#define     START                  {
#define     END                       }
#define     BLANK_LINE     printf(“\n”);
#define      INCREMENT      ++
if (total EQUALS 240 AND average EQUALS 60) INCREMENT count;

Macros With Arguments

  • More complex and more useful form of replacement
  • #define identifier(f1,f2,…..,fn)   string
  • No space between id and the left (
  • Subsequent occurrence of a macro with arguments is known as a macro call
  • When macro is called, the preprocessor substitutes replacing formal with actual parameters

A Simple Example of Macros With Arguments (MWA)

#define CUBE(x) (x*x*x)
 volume = CUBE (side)   // (side * side * side)
 volume = CUBE (a + b) would expand to
 volume = (a + b * a + b * a + b)
So #define CUBE (x) ( (x) * (x) * (x) )is a correct definition, which expands to
 volume = ((a +b) * (a + b) * (a + b)) 

Some Commonly Used Definitions

#define    MAX(a,b)     (((a) > (b)) ? (a) : (b))
#define    MIN(a,b)      (((a) < (b)) ? (a) : (b))
#define   ABS(x)          (((x) > 0) ? (x) : (-x))
#define STREQ(s1,s2) (strcmp((s1),(s2)) ==0)
#define STRGT(s1,s2) (strcmp((s1),(s2)) > 0)
#define PRINT(variable, format)           printf (“variable = %format \n”, variable);
PRINT (price * quantity, f)

Nesting of Macros

#define    M                    5
#define    N                     M + 1
#define  SQUARE(x)   ( (x) * (x) )
#define  CUBE(x)       ( (SQUARE(x)) * (x) ))
#define SIXTH(x)  ((CUBE(x)) * (CUBE(x)))

The preprocessor expands each macro, until no macro appear in the text

Nesting of Macro, File Inclusion

#define    HALF(x)          ( (x) / 2.0)
#define    ONE_4TH(x)   (HALF(HALF(x)))
#define    MAX(a,b)     (((a) > (b)) ? (a) : (b))

MAX(a,MAX(b,MAX(c,d))) can be used to find out maximum of a, b, c, d

#undef      <macro name>
#include    “filename”
#include   <filename>


Compiler Control Directives
  • They are used for problems being faced while developing large programs
  • They could be one of the following
    • You have included a file containing macro definitions, how would you know that a particular macro is defined ?
    • Suppose the customer has two different types of computers on which same program (that may have few diff lines in code) must run
    • They are used for problems being faced while developing large programs
    • They could be one of the following
    • You have included a file containing macro definitions, how would you know that a particular macro is defined ?
    • Suppose the customer has two different types of computers on which same program (that may have few diff lines in code) must run


Situation 1

  • Using conditional compiling the problem can be solved
#define   “DEFINE.H”
#ifndef    TEST
#define    TEST   1
#endif
  • See that #define TEST 1 or #undef TEST could result into problems

Situation 2 or 3


Situation 4

#ifdef TEST
{  printf(“Array Elements\n”);
   for (I=0;I<m;++I)
   printf(“x[%d]=%d\n”);  }
#endif

While debugging, we keep the TEST macro defined, when over, we undef it. 

#if Directive

  • #if constant expression
  • { …….}
  • #endif
  • The constant expression can be any logical expression such as
  •  TEST <= 3
  • (LEVEL == 1) || (LEVEL ==2)
  • MACHINE == ‘A’
  • #if defined -- New additions
  • #if !defined -- New additions


ANSI Additions

  • New preprocessor directives
  • #elif for alternative test facility
  • #pragma for specifying certain instructions to the compiler
  • #error to stop compilation when error occurs
  • New preprocessor operations
  • # Stringizing operator
  • ## Token pasting operator

#elif Directive

#if MACHINE == HCL
#define FILE “hcl.h”
#elif MACHINE == WIPRO
#define FILE “wipro.h”
#elif MCHINE == DCM
#define FILE “dcm.h”
#endif
#include FILE

Macros to Improve Portability, an Ex.

 #if MACHINE = DOS
    typedef size long int
    typedef smallsize int
 #elif MACHINE = UNIX || MACHINE = NT
    typedef size int
    typedef smallsize short int
 #endif     

Above code let the program to use size type variables to have 32 bit and smallsize type variables to have 16 bit irrespective of the machine type

Stringizing Operator #

  • #define sum(x)   printf(#x “=%f\n”,x)
  • sum (a+b) will be expanded to 
  • printf(“a+b” “=%f\n”,a+b) which is equivalent  to 
  • printf(“a+b=%f\n”,a+b) 
  • ANSI standard also stipulates that adjacent strings will be concatenated


Token Pasting Operator ##

  • It helps us in combining two tokens within a macro definition to form a single token
#define combine(s1,s2) s1 ## s2
 printf(“%f”,combine(total,sales));
 printf (“%f”, totalsales)
#define print(I) printf(“a#I”= %f”,a##I)
 print(5) will become
 printf(“a5 = %f”,a5);





  
Share: 

 
 

Didn't find what you were looking for? Find more on Preprocessor Or get search suggestion and latest updates.

Ella Brown
Ella Brown author of Preprocessor is from London, United Kingdom.
 
View All Articles

 
Please enter your Comment

  • Comment should be atleast 30 Characters.
  • Please put code inside [Code] your code [/Code].

 
No Comment Found, Be the First to post comment!