پیش‌پردازندهٔ ماکرو (macro)

به خطوطی که با علامت هش (hash sign) (#) شروع می‌شوند، پیش‌پردازنده (Preprocessor) می‌گویند. این خطوط دستورات برنامه نیستند و دستورالعمل پیش‌پردازنده هستند. پیش‌پردازنده قبل از شروع ترجمه (Compilation) کد را بررسی می‌کند و اقدامات لازم را انجام می‌دهد. پیش‌پردازنده‌ها تنها در یک خط نوشته می‌شوند و به محض اینکه خط جدیدی شروع می‌شود، دستورات پیش‌پردازنده پایان می‌یابد. تنها روشی که یک دستورالعمل پیش‌پردازنده می‌تواند در بیش از یک خط گسترش یابد، این است که در انتهای خط، یک بک‌اسلش (backslash) (\) قرار داده شود.

پیش‌پردازنده‌ها انواعی دارند:
۱. Source file inclusion (#include): درج فایل منبع
۲. macro definitions (#define, #undef): تعاریف کلان
۳. Conditional inclusions (#ifdef, #ifndef, #if, #endif, #else and #elif): اجزاء شرطی
۴. Line control (#line): کنترل خط
۵. Error directive (#error): دستورالعمل خطا
۶. Pragma directive (#pragma): دستورالعمل پراگما

macro definitions (تعاریف کلان):

برای تعریف پیش‌پردازندهٔ ماکرو از define# استفاده می‌شود. هنگامی که پیش‌پردازنده با این دستورالعمل روبرو می‌شود، دستورالعمل را با هرگونه شناسه در مابقی کد، جایگزین می‌کند. این جایگزینی می‌تواند یک بیان (expression)، یک عبارت (statement)، یک بلاک (block) و یا هر چیز ساده‌ای (simply anything) باشد.

نمونه‌هایی از پیش‌پردازندهٔ ماکرو در کد زیر آورده شده است:

#include <stdio.h>

#define PI 3.141592
#define GoldenRatio 1.618033
#define E 2.718281
#define INCREMENT(x) ++x
#define DECREMENT(x) --x
#define incnum(x) (x + 1)
#define decnum(x) (x - 1)
#define min(x, y) (x < y ? x : y)
#define max(x, y) (x > y ? x : y)
#define STRING(x) #x
#define mulMacro(x, y) x * y
#define MULMacro(x, y) (x) * (y)
#define EVEN_ODD(x) ((x) & 1) ? "ODD" : "EVEN"
#define concat(x, y) x##y
#define printVarValue(varName, ID) printf("Variable "#varName""#ID" = %d\n", varName##ID)
#define PrintHello(i, limit) while(i < limit)\
                             {\
                                 printf("Hello ");\
                                 i++;\
                             }

int main()
{
    int a = 16;

    printf("%f\n", PI);
    printf("%f\n", E);
    printf("%f\n", GoldenRatio);
    printf("%d\n", INCREMENT(a));
    printf("%d\n", incnum(5));
    printf("%d\n", min(12, 7));
    printf("%s\n", STRING(Olive Tree));
    printf("%d\n", mulMacro(2 + 3, 3 + 5));
    printf("%d\n", MULMacro(2 + 3, 3 + 5));

    int c = 7;
    printf("The number %d is %s\n", c, EVEN_ODD(c));

    int g = 3, h = 5, gh = 48;
    printf("%d\n%d\n%d\n", g, h, concat(g, h));
    printf("%d\n", concat(1234, 5678));

    int var1 = 10, var2 = 20;
    printVarValue(var, 1);
    printVarValue(var, 2);

    int i = 0;
    PrintHello(i, 3);
    printf("\ni = %d\n", i);

    return 0;
}