You learned about C preprocessor directives and its components earlier. These directive are of four types – macro expansion, file inclusion, conditional compilation ,and other miscellaneous directives. The macro expansion is the most common and popular C preprocessor directives.
Before you begin, learn a bit about the preprocessor directives. If you are familiar with the concept, skip ahead.
A macro is a small piece of code or constant value that is replaced with C source code before the execution of a C program. This concept is same as inline codes defined using the keyword inline.
What is a macro expansion?
To understand the concept of macro expansion, consider an example program code given below. The program used the #define directive.
#include <stdio.h>
#include <stdlib.h>
#define LENGTH 10
#define BREADTH 20
int main()
{
int area_rectangle = 0;
area_rectangle = LENGTH * BREADTH;
printf("Area of Rectangle = %d\n",area_rectangle);
system("PAUSE");
return 0;
}
Output
Area of Rectangle = 200
The LENGTH and BREADTH are called the macro templates. The values 10 and 20 are called macro expansions.
When the program run and if the C preprocessor sees an instance of a macro within the program code, it will do the macro expansion. It replaces the macro template with the value of macro expansion.
The #define
directive is a good way of declaring constant compared to a constant or a variable value. To change the constant, you must change it in all place in source code individually. The macro on the other hand only requires you to change the value of the #define
directive.
Another advantage of macro expansion is that it is much faster than the variables or constants.
Usage of #define Directive
The #define
directive is not only used to label a constant, but also other types of statements. The following program that demonstrates other possible usage of a #define
directive.
#include <stdio.h>
#include <stdlib.h>
#define AND && // define an operator
#define OR ||
#define CONDITION1 (p > 10) AND (q < 100) // define a condition
#define CONDITION2 (q > 100)
#define STATEMENT1 printf("p is greater than 10\n");
#define STATEMENT2 printf("q is greater than 100\n"); //print statements
int main()
{
int p,q;
p = 13;
q = 10;
if(CONDITION1)
{
STATEMENT1
}
else if(CONDITION2)
{
STATEMENT2
}
system("PAUSE");
return 0;
}
Output
p is greater than 10
In the above program, we defined three different types of macro templates – operators, conditions, and statements. In other words, all elements of a program are suitable for macro expansion. You can use operators, replace conditions or execute any code, the preprocessor will replace it into a source code (macro expansion).
It is not a good practice to use large piece codes for the macro expansion. The next section is about complex macros that do exactly the same.
Macros with Arguments
The complex macros take arguments like functions and it looks like a function. But there is a big difference between complex macro and a C function. See the example below.
#include <stdio.h>
#include <stdlib.h>
#define SQUARE(x) (x * x)
int main()
{
int n;
int result;
n = 5;
result = 0;
result = SQUARE(n);
printf("Result = %d\n",result);
system("PAUSE");
return 0;
}
Output3
Result = 25
The macro template takes argument x which is a value of the appropriate type(integer for multiplication). Whenever the C preprocessor sees SQUARE(x) in the program source code, it replaces it with ( x * x).
The x in the SQUARE(x)
is an argument. So the macro expansion of SQUARE(n)
becomes (n * n)
where n has a value assigned to it.
Common Mistakes while using #define
Mistakes happen when you write your programs, especially when you are new to C programming. A list of common mistakes while using a #define
directive is given below.
- Forgetting the # sign that results in a compiler error
- Not choosing a meaningful name for macro templates
- Using too many #define directives
- Using { } braces instead of ( ) in complex macros.
- Leaving a gap between macros – AREA (x) (x * x). This will result in compiler error.
In the next section, we will discuss about file inclusion
preprocessor directives.