12.6 – Macros with arguments

by subbu on December 19, 2013

Macros with arguments

Like a function, even a macro can be defined with arguments. It has the name, arguments and replacement text.

Macros with arguments

Here rather sending arguments and returning value, it works purely on textually substitution. The replacement text is just substituted by preprocessor wherever Macro accurse.

Now we see the fact through an example

#include<stdio.h>
#define MAX(x,y) x>y?x:y
#define MIN(x,y) x<y?x:y
int main()
{
 int a,b,big,small;
 printf("Enter two numbers:\n");
 scanf("%d%d",&a,&b);
 if(a==b)
   printf("Equal");
 else
 {
   big=MAX(a,b);
   small=MIN(a,b);
   printf("Biggest number %d",big);
   printf("\nSmallest number %d",small);
 }
 return 0;
}

Execution:
Enter two numbers:
45
45
Equal

Execution:
Enter two numbers:
45
12
Biggest number 45
Smallest number 12


 prog.c 4: int main()
 prog.c 5: {
 prog.c 6: int a,b,big,small;
 prog.c 7: printf("Enter two numbers:\n");
 prog.c 8: scanf("%d%d",&a,&b);
 prog.c 9: if(a==b)
 prog.c 10: printf("Equal");
 prog.c 11: else
 prog.c 12: {
 prog.c 13: big=a>b?a:b;
 prog.c 14: small=a<b?a:b;
 prog.c 15: printf("Biggest number %d",big);
 prog.c 16: printf("\nSmallest number %d",small);
 prog.c 17: }
 prog.c 18: return 0;
 prog.c 19: }

By looking at the expanded source we could observe that, MAX(a,b) is replaced with its replacement text a>b?a:b and MIN(a,b) is replaced with its replacement text a<b?a:b
Care must be taken while writing macros with arguments. It is always better to see the expanded source to see how the macros are getting replaced in the source
Now we will see some of the cases where logic may go wrong due to improper testing of macro definitions

Example: 


#define SQUARE(x) x*x

Wile using this macro, the replacement text to SQUARE(10) is 10*10. There may be no problem with this.
The replacement text to SQUARE(3+1) is 3+1*3+1, which results 7 instead 16. It is because * has more priority than +, hence 1*3 evaluates first and then 3, 1 are added to the result
It can be rectified by modifying the macro definition as


#define SQUARE(x) (x)*(x)

So that, the replacement text to SQUARE(3+1) would be (3+1)*(3+1), which results 16

What would be the output of following program?


#include<stdio.h>
#define S(x) x*x
int main()
{
 int a,b,c,d,e;
 int n=10;
 a=S(5);
 b=S(2+2);
 c=S(3+1);
 d=S(1+3);
 e=S(++n);
 printf("a=%d",a);
 printf("\nb=%d",b);
 printf("\nc=%d",c);
 printf("\nd=%d",d);
 printf("\ne=%d\n",e);
 return 0;
}
Show Output

Output:
a=25
b=8
c=7
d=7
e=144

Now we will realize this by looking at its expanded code


 prog.c 3: int main()
 prog.c 4: {
 prog.c 5: int a,b,c,d,e;
 prog.c 6: int n=10;
 prog.c 7: a=5*5;
 prog.c 8: b=2+2*2+2;
 prog.c 9: c=3+1*3+1;
 prog.c 10: d=1+3*1+3;
 prog.c 11: e=++n*++n;
 prog.c 12: printf("a=%d",a);
 prog.c 13: printf("\nb=%d",b);
 prog.c 14: printf("\nc=%d",c);
 prog.c 15: printf("\nd=%d",d);
 prog.c 16: printf("\ne=%d\n",e);
 prog.c 17: return 0;
 prog.c 18: }

Specification: Accept the radios and print the area, circumference using macros AREA, CIR


#include<stdio.h>
#define PI 3.14
#define AREA(x) (PI*x*x)
#define CIR(x) (2*PI*x)
int main()
{
 int rad;
 float a,c;
 printf("Enter the radios:");
 scanf("%d",&rad);
 a=AREA(rad);
 c=CIR(rad);
 printf("Area of circle %f",a);
 printf("\nCircumference of circle %f",c);
 return 0;
}

Execution:
Enter the radios: 5
Area of circle 78.500000
Circumference of circle: 31.400000

Specification: Accept any character and print whether the character is a vowel, consonant, digit or special symbol


#include<stdio.h>
#define AND &&
#define OR ||
#define ISVOWEL(x) (x=='a' OR x=='e' OR x=='i' OR x=='o' OR x=='u')
#define ISCONS(x) (x>='b' AND x<='z')
#define ISDIG(x) (x>='0' AND x<='9')
int main()
{
 char alp;
 printf("Enter any alphabet:");
 scanf("%c",&alp);
 if(ISVOWEL(alp))
  printf("Vowel");
 else if(ISCONS(alp))
  printf("Consonant");
 else if(ISDIG(alp))
  printf("Digit");
 else
  printf("Spacial symbol");
 return 0;
}

Execution:
Enter any alphabet: 7
Digit

Macro vs. function:
In the above examples, macros were used to calculate area, circumference of circle and to find category of a character. Though macro calls are similar to function calls, they are not really same things.
In case of macros, replacement text is just replaced with macro along the source. It increases the size of source code but increases the performance of program because in case of functions, it takes time to call a function and getting control back
Complex logic can’t be replaced with macros rather functions need to be used
In case of functions, size of source code would not be changed as we call the function for any number of times but, takes some time every time a function is called. Complex logic can be implemented using functions, but not possible with macros
Conclusion is that, use macro where speed is critical and used functions, where space is critical

Macro parameters are generic:

Unlike functions, formal arguments of a macro are generic, accepts any type of actual arguments. Say for example, if we want to define a function that takes two integers and returns sum of them then the function would be


int sum(int x,int y)
{
 return x+y;
}

If we want to define a function that accepts two floating point values and returns sum of them then the function would be


float sum(float x,float y)
{
 return x+y;
}

In case of macro with parameters, it is enough to define a single macro to handle both integer and floating point types.


#include<stdio.h>
#define SUM(x,y) (x)+(y)
int main()
{
 int s1=SUM(10,20);
 float s2=SUM(12.34f,56.34f);
 printf("Sum of integers %d",s1);
 printf("\nSum of floating point types %f",s2);
 return 0;
}

Output:
Sum of integers 30
Sum of floating point types 68.680000

Previous post:

Next post: