Using Macro in C/C++

    
#ifndef __CAR_H__
#define __CAR_H__
class Car
{
private:
    char color[20];
public:
    void setColor(char* color);
    char* getColor();
};
#endif


Why guards are required ?
To find the answer of this question just have a look in the below mentioned example.

I have four classes, that is Car, Hyundai , Suzuki and Showroom. 
Hyundai and Suzuki is extended from Car. Showroom is having Hyundai and Suzuki.

Car.h

class Car
{
private:
    char color[20];
public:
    void setColor(char* color);
    char* getColor();
};
Hyundai.h
#include "Car.h"

class Hyundai : public Car
{
private:
    char name[20];
public:
    void setName(char* color);
    char* getName();
};

Suzuki.h

#include "Car.h"


class Suzuki : public Car
{
private:
    char name[20];
public:
    void setName(char* color);
    char* getName();
};
Showroom.h

#include "Hyundai.h"
#include "Suzuki.h"

class Showroom
{
private:
    Hyundai HyndaiCar[20]; // 20 Hyundai car objects
Suzuki SuzukiCar[20];  // 20 Suzuki car object
public:
    //some function
};


Now the problem in the above example is class Showroom is including Hyundai.h and Suzuki.h, and Hyundai.h is including Car.h and Suzuki.h is also including Car.h. That means the content of Car.h is included two times in Showroom.h which is illegal and compiler will throw error related to duplicate definition.

This problem can be resolved by using macro guards as discussed above.
While including Hyundai.h compiler will include Car.h and define __CAR_H__ first time, then it will include Suzuki.h which also includes Car.h but this time __CAR_H__ is already defined so the content below ifndef will not be included. And finally only one copy of content from Car.h will be there in Showroom.h.



Define/Undefine a constant by using #define/#undef macro.

Macro can be used to define a literal for example:
#define PI 3.14
and it can be used later in the program like
#define PI 3.14
int radius=5;
int areaOfCircle=PI*r*r;
#undef PI
Another Example:
#define MAX_SIZE 50
int main()
{
    char arr[MAX_SIZE]; //creates an array of size 50
#undef MAX_SIZE
    //char arr2[MAX_SIZE]; //gives compiler error MAX_SIZE not defined
#define MAX_SIZE 100
    char arr3[MAX_SIZE]; //creates an array of size 100
#undef MAX_SIZE
}

Function-like Macros

The #define directive allows the macro name to have arguments thus it can behave like a function. Such forms of macros are referred as Function-like Macros.

For example:

#include "iostream.h"
 
#define MAX(a, b)    ((a < b) ? b : a)
 
int main( void)
{
    cout << "Maximum of 10 and 20 is " << MAX(10, 20) << endl;
    return 0;
}

Cross Platform compilation

As C/C++ language is known for systems programming (ex: embedded programming, OS kernel, Hardware drivers etc...), with performance, efficiency and flexibility. Since there are many architecture of processors and operating system exist in this world which has its own instructions and specifications. Because of this any program created for one platform may not work in different vendor of processors/operating-systems. There are many compiler vendors as well who has their own library, therefore the program compiled in one compiler may not compile in another compiler because their library may differ. Ex: Terbo C/C++ has "conio.h" where GNU/Linux C/C++ doesn't provides this library. So same code which will execute properly in Windows might fail in Linux.
To create a program which will use the library based on the platform is possible by using macro. 
Example is shown below:

    
#include <stdio.h>
#ifdef __WIN32__
    #include <conio.h>     //if windows os
#endif

void printTable(int num)
{
        int i=1;
        for(i=1;i<=10;i++)
        {
                printf("%d x %d = %d\n",num,i,num*i);
        }
}
int main(void) {

    char ch;
    int num;
    do
    {
            printf("Enter a number:");
            scanf("%d",&num);
            printf("Table of %d is:\n",num);
            printTable(num);
            printf("Press c to continue:");
            while((ch=getchar())!='\n');
            scanf("%c",&ch);
        #ifdef __WIN32__
            clrscr();           //if windows os
        #else
            system("clear");    // if linux os
        #endif  
    }while(ch=='c');
    return 0;
}

No comments :

Post a Comment