What is #define Directive in C Program?

This C Tutorial explains #define Directive in a C Program.

#define directives are preprocessor directives. These are either symbolic constants or macros or conditional compilation constructs or other various directives. Let’s see first symbolic constants, for ex.,

#define NAME "What is your name?"
#define SIZE 512
#define PI   3.14
 
#define FOREVER   for(;;)
#define PRINT     printf("values of x = %d and y = %d.\n", x, y)

Notice that we haven’t used ‘;’ to terminate the replacement texts in each #defined symbol above. Actually, when we use them in program, for ex.

int main(void)
{
    char buf[SIZE];
    int x = 10, y = 20;
 
    FOREVER;  /* ; used here */
 
    PRINT;
    x++;
    y++;
 
    PRINT;
 
    return 0;
 
}

‘;’ is used to terminate the symbolic statement as any other C statement. Let’s see what happens when preprocessor operates on the main() above, it becomes,

int main(void)
{
    char buf[512];
    int x = 10, y = 20;
 
    for(;;);
 
    printf("values of x = %d and y = %d.\n", x, y);
    x++;
    y++;
 
    printf("values of x = %d and y = %d.\n", x, y);
 
    return 0;
 
}

So what do you think how will it affect the program execution if you have used ‘;’ in the replacement text, for ex.,

advertisement
advertisement
#define PRINT   printf("values of x = %d and y = %d.\n", x, y); /* ';' */

and then used #define PRINT in program and preprocessed it, output results as follows,

int main(void)
{
    printf("values of x = %d and y = %d.\n", x, y);;
 
    return 0;
}

If you notice the main() above, the extra ‘;’ doesn’t affect the program execution. But now consider,

Note: Join free Sanfoundry classes at Telegram or Youtube
#include <stdio.h>
#define TRUE 1
#define PRINT    printf("values of x = %d and y = %d.\n", x, y);
 
int main(void)
{
    if (TRUE)
        PRINT;
    else
        printf("Bye!\n");
 
    return 0;
}

Notic that extra ‘;’ causes compilation error in the program. So, it’s always a rule to use ‘;’ to terminate the symbolic constants in program and not in their definitions.

Let’s now consider #define macros, for ex.,

#define MUL(a,b)   a * b

and use MUL(a,b) in program as,

advertisement

int main(void)
{
printf(“product of 5 and 10 is %d\n”, MUL(5,6));
return 0;
}

Of course, output displays as

product of 5 and 10 is 50

Now, guess what’ll be the output if you use macor arguments as,

advertisement
int main(void)
{
    int x = 10, y = 10;
 
    printf("product of %d and %d is %d\n",
            x + 1, y + 1, MUL(x + 1, y + 1));
 
}

Output displays as,

product of 11 and 11 is 21

It’s not correct at all! Why? Where have execution gone wrong? Let’s explore this by substituting

macro MUL(x + 1, y + 1) by it’s definition in the printf() below,

    printf("product of %d and %d is %d\n",
            x + 1, y + 1, MUL(x + 1, y + 1));

Preprocessor does substitution as follows,

    printf("product of %d and %d is %d\n",
            x + 1, y + 1, x + 1 * y + 1);

And cause gets cleared! Firstly,

1 * y

multiplied, expression became

10 + 10 + 1

which resulted 21. This problem can be easily fixed by using parenthesis in macro declaration as

#define MUL(a,b)  ((a) * (b))

Remember that every operand and entire arithmetic expression in macros definition should be properly parenthesised to avoid unexpected results because of adajacent operators in expressions, and within the macro definitions.

Actually, symbolic constants make programs easily maintainable by allowing them to be modified just at their place of declaration irrespective of size of program and how many different places have these been used in program! For ex.,

#include <stdio.h>
#define SIZE  10
 
void disp(char []);
 
int main()
{
    char name[SIZE] = {'a', 'b', 'c', 'd', 'e', 'f', 'g',
                             'h', 'i', 'j'};
    disp(name);
    return 0;
 
}
 
void disp(char name[])
{
    int i;
 
    printf("name is: ");
    for (i = 0; i < SIZE; i++) {
         printf("%c", name[i]);
    }
 
    printf("\n");
}

Notice that had symbolic constant SIZE even required to be modified, it would have to be updated at one place in the program irrespective of program size. Further, scope of #define symbols is throughout the program from the point of declaration.

Let’s come to function-like macros. Where do macros play role in C programs? We have already used MUL(a,b) macro to compute product of two values. What type of values were those? We had used integers there. Of course, we can use MUL(a,b) to compute product of any type of values, whether integers, floats, double, unsigned integers, etc. This means, macros are typeless! Well! We could rather use functions but then we should have declared functions, one for each type of arguments. In addition,
there’s overhead in function call and return. Therefore, macros are efficient over functions where they are very small in size.

Sanfoundry Global Education & Learning Series – 1000 C Tutorials.

If you wish to look at all C Tutorials, go to C Tutorials.

advertisement
advertisement
Subscribe to our Newsletters (Subject-wise). Participate in the Sanfoundry Certification contest to get free Certificate of Merit. Join our social networks below and stay updated with latest contests, videos, internships and jobs!

Youtube | Telegram | LinkedIn | Instagram | Facebook | Twitter | Pinterest
Manish Bhojasia - Founder & CTO at Sanfoundry
Manish Bhojasia, a technology veteran with 20+ years @ Cisco & Wipro, is Founder and CTO at Sanfoundry. He lives in Bangalore, and focuses on development of Linux Kernel, SAN Technologies, Advanced C, Data Structures & Alogrithms. Stay connected with him at LinkedIn.

Subscribe to his free Masterclasses at Youtube & discussions at Telegram SanfoundryClasses.