C Programming Tutorial

C Preprocessor Directives

        Preprocessor directives performs macro definition,source code file inclusion,and conditional compilation. and line control

it is a seperate program invoked by the C Compiler. C has a Built-in Preprocessor that isolate any system dependent code.

#define LIMIT 100 //Here LIMIT is called as a symbolic constant

Lines that start with # are called Preprocessing Directives

scope of the preprocessing directive the line it starts in a file to end of the file.

Preprocessor doesnot know 'C', it is a independent program invoked by compiler,these independent program replaces all symbolic constants with the macors,after that actual compilartion starts.

Job of Preprocessing

  • Replacing Symbolic Names with constants
  • Expansion of macros
  • file inclusion

Filename Inclusion

        File name inclusion can be done in following ways

searches for file in system standard directories and then other directories

		#include <filename>

searches for file first in current directory and then other directories

		#include "filename"

Symbolic Constants & Macros

        Symbolic Constants Given a Name to a value.

#define PI 3.14159

here PI is a symbolic constant

Preprocessing directive program, whereever symbolic constant PI occurs in any expressions in source code ,it replaces with value 3.14454, this process happens before compilation of the C source code

Passing arguments

User can pass arguments with macros

#define MAX(a,b) ((a)>(b))?(a):(b)

Passing arguments to macro,MAX macro takes 2 arguments irrelevant of the type

Calling macros in source code





Calling macros within macros or nested macros

define a simple macro called
#define SQR(X) (x) * (x)
printf("%d",SQR(5)) will print square of 5 is 25. again calling SQR within SQR , means SQR(SQR(5)) gives 625. nested macro expanded first, 5*5 25 replaces SQR(5),now SQR(25) expanded, 25 * 25 gives 625

This type of macros has side effects for ex: int a=10; printf("%d",SQL(a++)) ,SQR will be expanded as (a++) * (a++) , a has value 10, (11)*(10) gives 110. now print "a" value, gives 12, because "a" is incremented twice. programmer must avoid such expressions in macros.

comparing 2 strings using macros

define simple macro called COMPARE which accepts 2 arguments string1 and string2, if both strings are equal displays message "strings are equal " otherwise not equal.

#define  COMPARE(s1,s2)   if(strcmp(s1,s2)==0) printf("strings are equal\n"); \
                          else printf("strings are not equal\n");

#multi-line  macro , end of first line should be backslash \ to indicate continous

COMPARE("sam","sam"); COMPARE("RAM","sam"); prints "strings are equal" and "strings are not equal",respectively.

Swapping 2 numbers using macros

#define SWAP(x,z,temp) {temp=x;x=y;y=temp;}

exchange 2 values using third variable. copy x value to temp, now temp hold value of x, so x value can be erasable, means copy y value to x,because temp already has x value, finally copy temp value i.e x value to y

calling SWAP macro

	#define SWAP(x,z,temp)  {temp=x;x=y;y=temp;}
        double x=10.12,y=20.25,temp;

Predefined macros

  • __DATE__ macro
  • __FILE__ macro
  • __LINE__ macro
  • __STDC__ macro
  • __TIME__ macro

Conditional Compilation

#if,   #ifdef,   #ifndef,   #elif,   #else,   #endif

Preprocessing Operators # and ##

# Operator

      The unary operator # is used to "stringization" of macro parameter.It is also called as creation of strings

#define TOK(a) printf(#a)

    TOK(Hello World);
Preprocessor directive replaces formal parameter of Macro with printf statement,argument sorrounded by double quotes Whenever TOK(10);is called it is replaced with printf("10"); TOK(Hello) with printf("hello"); TOK(Hello World) with printf("Hello World");
	Hello World

Converting Enum to String

Enum constant values can be converted to String using unary Preprocessor # operator

#define TOK(a) printd(#a)
ouputs RED as a string, BLUE as a String. etc.,

## Operator

      The binary operator ## is used to merge tokens.

assert() macro usage

      Assert macros are defined in "assert.h". assert macros are very usefull in validating data. otherwise control statements should be used to test a data.in that case code becomes cumbersome and error-prone, in order to avoid that assert macro helps us to write clean code for validating input data.

if assertion fails displays error message and exits the application

int a=3,b=4; assert(a+b != 7); Assertion `(a+b)!=7' failed. Aborted (core dumped)

if you call like this assert(a+b == 7); validation successful, it continues with next statement

Preprocessing defined operator