Macro expansion
Let see an example of macro:
1 2 3 4 5 6 7 8 9 |
#define SIZE 5 int main() { int i ; for ( i = 1 ; i <= SIZE ; i++ ) { printf ( "%d", i ) ; } } |
Here preprocessor name of macro is SIZE which has already been defined before main( ).
1 |
#define SIZE 5 |
This statement is called ‘macro definition’ or just ‘macro’.
Preprocessor replaces the name of macro i.e, SIZE with 5 with every occurrence of SIZE in the program.
These replace part will be given to the compiler for compilation before the source code passes to the compiler.
When compiler sees the #define, it goes through the entire program and replaces all the macro template with the appropriate macro expansion.
Lets see another example
1 2 3 4 5 6 7 8 9 |
#define X 5+5 int main { int result ; result= X+X+X; printf ( "%d", result ) ; } /* Output: 30 */ |
Notes
- Here, SIZE and X are called as ‘macro templates’, whereas, 5 and 5+5 are called their corresponding ‘macro expansions’.
- A macro template and its macro expansion are separated by blanks or tabs.
- A space between # and define is optional.
- A macro definition is never to be terminated by a semicolon.
- In C programming it is customary to use capital letters for macro template.
- A #define directive could be used even to replace a condition.
- A #define directive could be used to replace even an entire C statement.
- A macro can be redefine.
Why use #define?
Using #define you can produce more efficient and more easily understandable programs.
Probably, we have made the program easier to read.
Suppose we use a value of SIZE is 5 in a program and it appears many times in your program.
This value may have to be changed.
Then you need to go through the program and manually change each occurrence of the SIZE.
Therefore, if you have defined SIZE in a #define directive, you only need to make one change, in the #define directive.
Difference between macro and function.
- Usually macros make the program run faster but increase the program size, whereas functions make the program smaller and compact.
- In function, execution time is more because passing arguments to a function and getting back the returned value does take time.
This gets avoided with macros since they have already been
expanded and placed in the source code before compilation. - In function data type checking is done, whereas in macro data type checking is not done.
Examples of #define:
- Example of macro with arguments
123456#define f(a,b) a+b#define g(c,d) c*dint main(){printf("%d",f(4,g(5,6))); //34}
Here firstly, g(5,6) is replace by 5*6 i.e equals to 30.
Then f(4,30) is replaced by 4+30 = 34.
Therefore it prints 34 as output. - macros can be redefine.
123456#define MAX 60#define MAX 28void main(){printf("%d",MAX); // 28} - The directives can be placed anywhere in a program.
12345void main(){#define MAX ' ' // allowprintf("%d",MAX); // 32}
Here ASCII value of space i.e. 32 will print. - .
1234567#define RES(x) x*xint main(){int a,b=3;a=RES(b+2);printf("%d",a); //11}
a = RES(b+2)
= b+2 * b+2
= 3+2 * 3+2
= 3 + 6 + 2
=11 - macro templates should have macro expansion.
12345#define MAXint main(){printf("%d",MAX); // error} - If macro template is written inside ” ” then, macro template won’t be replace by macro expansion.
12345#define HELLO 44int main(){printf("%d","HELLO"); // 573582(base address of string)} - .
1234567#define a 5+2int main(){int ans;ans = a*a*a;printf("%d",ans); // 27}
ans = a*a*a = 5+2 * 5+2 * 5+2 = 5 + 10 + 10 + 2 = 27 - .
123456#define int doubleint main(){int i=100;printf("sizeof(i) = %d", sizeof(i)); // 8 bytes}