c programming preprocessors

c programming preprocessors

The header file section and global declaration section are valued for providing unique functions to carry out program execution smoothly in the standard C program format.

In general terms the word preprocessor is a code written to provide input to a processor hence, in other words, a preprocessor is a processor to a processor. Inclusion of preprocessor also begins with a hash (#) symbol. But follows by a special word “define”. Hence, the preprocessor declaration is also known as a global declaration, since, the value once defined in this section can be applied once cannot be changed in the remaining program. Though they can be declared anywhere in the program, it is often good practice to declare it at the beginning.

The preprocessor offers several features called preprocessor directives. These directives can be divided into four categories:

  • Macro substitution directives
  • File inclusion directives
  • Conditional compilation
  • Miscellaneous directives

Macro substitution directives

Macro substitution is a process where an identifier in a program is replaced by a predefined string composed of one or more tokens. a macro definition takes the following general form: #define Identifier String

Note:

  • #define is written just as shown followed by the identifier and a string.
  • It should not be ended semicolon.
  • At list one blank space required between an identifier and a string.
  • The string may be any text, which the identifier must be a valid name.

File inclusion directives

This directive causes one file to be included in another. The preprocessor command for file inclusion looks like this: #include “filename”. And it simply causes the entire contents of filename to be inserted into the source code at the point in the program. It can be used in two cases:

If we have a very large program, the code is best divided into several different files, each containing a set of related function. It is very good programming practice to keep different sections of a larger program separates. These files are #include at the beginning of the main program file.

There are some function and macro definitions that we need almost in all the programs that we write. These commonly needed functions and macro definitions can be stored in a file, which would add all the statements in this file to our program as if we have typed them in.

Syntax:  #include <filename.h> or #include "filename.h"

Note:

  • If we are including any file from default directory then we have to use #include <filename.h>
  • if we are including any file from current project working directory then we have to use #include "filename.h"

Header files

Every C program consists of certain provision of header files, provided at the top of the main() function. They generally begin with the symbol “#” followed by a predefined word “include”.  

With the inclusion of header file prior to main() function facilitates us to use or declare various functions, prototypes … etc which are nothing but the constituent entities of declared header files. Example, <stdio.h> header file facilitates us to carry out various I/O functions in our “C” program. Functions like printf(), scan() possess a predefined code in the stdio library.

Note:

  • Every header file possess ‘.h’ extension.
  • It is possible to create our own header files.
  • In some compilers, few header files are pre-included. We need not require to write include before main().

Conditional compilation

Conditional compilation is a preprocessor directive which is used to tell the compiler to skip some part of source code. This is achieved by inserting the preprocessing commands #ifdef and #endif.

Advantages of conditional compilation

  • Conditional compilation allows to “comment out” obsolete lines of code.
  • It permits to have different versions of the same code in the same source file.
  • It makes the program portable i.e., it makes a program to work on two totally different computers.
  • It helps to ensure that header files are only once included in the program.

#define

We can, if we want, have the compiler skip over of source code by inserting the preprocessing commands #ifdef and #endif, which have the general form:

#define macroname 
void main() 
{ 
   #ifdef macroname 
      Statement1; 
      Statement2;
      Statement3; 
   #endif 
      Statement4;
}

If macroname has been #define, the block of code will be processed as usual, otherwise not. Where would #ifdef be useful? When do you like to compile only a part of your program? In these cases: To “comment out” obsolete of code.

More sophisticated use of #ifdef has to do with making the program portable, i.e. to make them work on two totally different computes.

Example1:

#include <stdio.h> 
int main() 
{ 
      printf("BT\n"); 
      #ifdef BT 
          printf("WELCOME BALU TUTORIAL\n"); 
          printf("HELLO\n"); 
      #endif 
      printf("BALU TUTORIAL\n");    
      return 0;
}

Output:

BT

BALU TUTORIAL

Example2:

#include <stdio.h> 
#define BT 
int main() 
{ 
       printf("BT\n"); 
       #ifdef BT 
         printf("WELCOME BALU TUTORIAL\n"); 
         printf("HELLO\n"); 
      #endif 
         printf("BALU TUTORIAL\n"); 
     return 0; 
}

Output:

BT

WELCOME BALU TUTORIAL

HELLO

BALU TUTORIAL

Example3:

#include <stdio.h> 
#define BT 
int main() 
{ 
      printf("BT\n"); 
      #ifdef BT 
         printf("WELCOME BALU TUTORIAL\n"); 
         printf("HELLO\n"); 
     #else 
         printf("C AND C++\n"); 
     #endif 
         printf("BALU TUTORIAL\n"); 
    return 0; 
}

Output:

BT

WELCOME BALU TUTORIAL

HELLO

BALU TUTORIAL

#if and #elif Directives

The #if directive can be used to test whether an expression evaluates to a nonzero or not. if the result of the expression is nonzero, then subsequent line up to a #else, #elif or #endif are compiled, otherwise, they are skipped.

int main() 
{ 
      #if condition 
            statement1; 
            statement2; 
            statement3; 
      #elif 
             statement4; 
             statement5; 
     #else 
         statement6; 
         statement7; 
     #endif 
     return 0; 
}

If the condition evaluates to true, then statement 1,2 and 3 are compiled, otherwise #elif will evaluates to true, then statement 4 and 5 are compiled, otherwise statement 6 and 7 are compiled.

Miscellaneous Directives

There are more preprocessor directives available, though they are not very commonly used. They are

  • #undef
  • #pragma
  • #error

Undefining a Macro: A defined macro can be undefined, using the statement

Syntax: #undef identifier

This is useful when we want to restrict the definition only to a particular part of the program.

#pragma Directive: The #pragra is an implementation oriental directive that you can use to turn on or off features. Pragma vary from one compiler to another. Turbo C/C++ compiler has got a pragma that allows you to suppress warning generated by the compiler.

#pragma startup and #pragma exit: These directives allow us to specify functions that are called upon program startup (before main( )) or program exit.

#pragma warn: On compilation, the compiler reports Errors and Warnings in the program if any. Errors provide the programmer with no option, apart from correcting them. Warnings, on the other hand, offer the programmer a hint or suggestion that something may be wrong with a particular statement. Two most common situation when the warning is displayed are us under:

Return type warnings.

Run-time errors, such as assigning a value that never used.

  • #pragma warn-rvl /* return valu*/
  • #pragma warn-par /*parameter not used */
  • #pragma warn-rch /*unreachable code */
#include <stdio.h> 
void btutorial(); 
void abc(); 
#pragma startup btutorial 
#pragma exit abc 
int main () 
{ 
      printf("inside main\n");
      return 0; 
} 
void btutorial() 
{ 
     printf("inside btutorial\n");
} 
void abc() 
{ 
     printf("inside abc\n"); 
}

Note:

That the function btutorial() and abc() should not return any value. If we want two functions to get executed at startup then their pragmas should be defended in the reverse order in which you want to get them called.

Stringizing Operator #: ANSI C providing operator # called stringizing operator to be used in the definition of macro functions. This operator allows a formal argument within a macro definition to be converted to a string.

#include <stdio.h> 
#define sum(xy) 
printf(#xy "=%d\n",xy) 
int main( ) 
{ 
     int a=5,b=10; 
     sum(a+b); 
     return 0; 
}

This preprocessor will convert the line sum(a+b) into printf (“a+b””=%d\n”,a+b); which is equivalent to printf (“a+b=%f\n”,a+b); 

Token Pasting Operator ##: The token pasting operator ## defined by ANSI standard enables us to combine two tokens within a macro definition to form a single token.

/* Hours to seconds conversion program */ 
#include <stdio.h> //header file inclusion declaration 
#define SEC 60 //Preprocessor declaration 
#define MIN 60 // Preprocessor declaration 
int main() 
{
     int HOUR=0, TIME_IN_SEC; 
     printf("Enter hours:"); 
     scanf("%d",&HOUR); 
     TIME_IN_SEC=HOUR*MIN*SEC; 
     printf("The time in seconds is %d",TIME_IN_SEC); 
     return 0;
}

Output:

Enter hours:12                                                                                                                                               
The time in seconds is 43200 

whatsapp

error: Content is protected !!