Рубрики

X-Macros в Си

X-макросы основаны на свойстве вложенных макросов и способности определять макросы внутри других макросов. X-макросы — это очень мощная технология препроцессора в том смысле, что она может создавать самостоятельный и взаимозависимый фрагмент кода. Если изменение одной части программы приводит к изменению другой части, то код называется взаимозависимым.

Синтаксис:
Приложение X macro состоит из двух частей:

  • Определение элементов списка:
    #define VARIABLES \
        X(value1, 1)  \
        .
        .
        .  \
        X(valueN, N)
    
  • Расширение (я) списка для генерации фрагментов объявлений или операторов:
    #define X(name) int name;
        VARIABLES
    #undef X
    

Список определяется файлом макроса или заголовка (с именем VARIABLES), который сам по себе не генерирует код, а просто состоит из последовательности вызовов макроса (классически называемого «X») с данными элементов. Каждому расширению VARIABLES предшествует определение X с синтаксисом для элемента списка. Вызов VARIABLES расширяет X для каждого элемента в списке.

Реализации:

  • Пример 1: Следующий код объясняет работу X-Macros:

    #include <stdio.h>

      
    // Определяет четыре переменные.
    #define VARIABLES \

        X(value1, 1)  \

        X(value2, 2)  \

        X(value3, 3)  \

        X(value4, 4)

      
    // драйверная программа.

    int main(void)

    {

        // Объявление каждой переменной

        // делается через макрос.

        #define X(value, a) char value[10];

            VARIABLES

        #undef X

          

        // Строковые значения принимаются

        // для всех переменных.

        #define X(value, a) scanf("\n%s", value);

            VARIABLES

        #undef X

          

        // Значения печатаются.

        #define X(value, a) printf("%d) %s\n", a, value);

            VARIABLES

        #undef X

        return 0;

    }

    Выход:

    1) geeks
    2) for
    3) geeks
    4) geeksforgeeks
    

    В приведенном выше коде добавление одной или нескольких переменных в макрос «VARIABLES» приведет к его автоматическому объявлению, сканированию и печати. Этот простой пример очищает работу и мощь X-Macros. После расширения приведенный выше код будет выглядеть следующим образом:

    #include <stdio.h>

      

    int main(void)

    {

        char value1[10];

        char value2[10];

        char value3[10];

        char value4[10];

      

        scanf("\n%s", value1);

        scanf("\n%s", value2);

        scanf("\n%s", value3);

        scanf("\n%s", value4);

      

        printf("%d) %s\n", 1, value1);

        printf("%d) %s\n", 2, value2);

        printf("%d) %s\n", 3, value3);

        printf("%d) %s\n", 4, value4);

        return 0;

    }

    Выход:

    1) geeks
    2) for
    3) geeks
    4) geeksforgeeks
    

    Хотя приведенный выше код просто объясняет мощь X-Macros, такое использование редко и не рекомендуется, потому что делает код менее читабельным. Более практичный пример — таблицы enum или jump.

  • Пример 2: Следующий код объясняет работу X-Macros с enum:

    #include <stdio.h>

      
    // Определение макроса
    // со значениями цветов.
    #define COLORS \

        X(RED)     \

        X(BLACK)   \

        X(WHITE)   \

        X(BLUE)

      
    // Создание перечисления цветов
    // путем расширения макроса.

    enum colors {

        #define X(value) value,

            COLORS

        #undef X

    };

      
    // Утилита, которая принимает значение enum
    // и возвращает соответствующее строковое значение

    char* toString(enum colors value)

    {

        switch (value) {

            #define X(color) \

                case color:  \

                    return #color;

                    COLORS

            #undef X

        }

    }

      
    // драйверная программа.

    int main(void)

    {

        enum colors color = WHITE;

        printf("%s", toString(color));

        return 0;

    }

    Выход:

    WHITE
    

    В приведенном выше коде любое добавление или удаление любой константы из макроса COLORS автоматически отразится в определении функции enum, а также функции toString (). Именно поэтому X-макросы используются для создания самоподдерживающихся кодов. После раскрытия макроса приведенный выше код будет выглядеть следующим образом:

    #include <stdio.h>

      
    // Создание перечисления цветов.

    enum colors {

        RED,

        BLACK,

        WHITE,

        BLUE

    };

      
    / * Утилита, которая принимает значение enum и возвращает
    соответствующее строковое значение * /

    char* toString(enum colors value)

    {

        switch (value) {

        case RED:

            return "RED";

        case BLACK:

            return "BLACK";

        case WHITE:

            return "WHITE";

        case BLUE:

            return "BLUE";

        }

    }

      
    // драйверная программа.

    int main(void)

    {

        enum colors color = WHITE;

        printf("%s", toString(color));

        return 0;

    }

    Выход:

    WHITE
    

Преимущества X-Macros

  • X-макросы широко используются при разработке операционной системы, создавая отдельные файлы заголовков для удобства обслуживания и удобства чтения.
  • Помогает легко поддерживать сложное программирование
  • он может создать самостоятельную и взаимозависимую часть кода

Недостатки X-Macros

  • Код становится менее читабельным
  • Код сложен для понимания
  • Обычно используется только для внутреннего программирования, например, для программирования ОС.

Ссылка: https://en.wikipedia.org/wiki/X_Macro

Рекомендуемые посты:

X-Macros в Си

0.00 (0%) 0 votes