Я уверен, что вы слышали слово «X Macro» в C, которым вы можете подытожить общий код вашего конкретного раздела в вашей программе. Я использую ту же концепцию, чтобы уменьшить количество строк в моем (визуальном) коде и позволить компьютеру писать код за меня. Прежде чем перейти к примеру, просто посмотрите на определение X-macro.
X-Макро
X-Macros основаны на свойстве вложенных макросов и возможности определять макросы внутри других макросов. X-Macros — очень мощный метод препроцессора в том смысле, что он может создавать самостоятельныйи взаимозависимый фрагмент кода.
Ниже приведен код с примером X-Macro,
#include <stdio.h> #define ALL_EVENTS \ X(EVENT_1) \ X(EVENT_2) \ X(EVENT_3) \ X(EVENT_4) #define ALL_STATES \ X(STATE_1) \ X(STATE_2) \ X(STATE_3) \ X(STATE_4) typedef enum _event_ { #define X(arg) arg, ALL_EVENTS #undef X }EVENTS; typedef enum _state_ { #define X(arg) arg, ALL_STATES #undef X }STATES; void print_event_state(EVENTS event, STATES state) { switch(event) { #define X(arg) case arg : printf("Event = "#arg); \ break; ALL_EVENTS #undef X } switch(state) { #define X(arg) case arg : printf(", State = "#arg"\n"); \ break; ALL_STATES #undef X } } int main() { print_event_state(EVENT_1, STATE_4); print_event_state(EVENT_2, STATE_3); print_event_state(EVENT_3, STATE_2); print_event_state(EVENT_4, STATE_1); }
Давайте обсудим, как препроцессор расширяет этот макрос.
Первый препроцессор разворачивает макрос ALL_EVENTS & ALL_STATE как,
typedef enum _event_ { #define X(arg) arg, X(EVENT_1) X(EVENT_2) X(EVENT_3) X(EVENT_4) #undef X }EVENTS; typedef enum _state_ { #define X(arg) arg, X(STATE_1) X(STATE_2) X(STATE_3) X(STATE_4) #undef X }STATES; switch(event) { #define X(arg) case arg : printf("Event = "#arg); \ break; X(EVENT_1) X(EVENT_2) X(EVENT_3) X(EVENT_4) #undef X } switch(state) { #define X(arg) case arg : printf(", State = "#arg"\n"); \ break; X(STATE_1) X(STATE_2) X(STATE_3) X(STATE_4) #undef X }
Затем он расширяет X (СОБЫТИЕ) и X (СОСТОЯНИЕ) как,
typedef enum _event_ { EVENT_1, EVENT_2, EVENT_3, EVENT_4, }EVENTS; typedef enum _state_ { STATE_1, STATE_2, STATE_3, STATE_4, }STATES; switch(event) { case EVENT_1 : printf("Event = ""EVENT_1); break; case EVENT_2 : printf("Event = ""EVENT_2); break; case EVENT_3 : printf("Event = ""EVENT_3); break; case EVENT_4 : printf("Event = ""EVENT_4); break; } switch(state) { case STATE_1 : printf(", State = ""STATE_1""\n"); break; case STATE_2 : printf(", State = ""STATE_2""\n"); break; case STATE_3 : printf(", State = ""STATE_3""\n"); break; case STATE_4 : printf(", State = ""STATE_4""\n"); break; }
Таким образом, вы можете не только написать менее (визуальный) код, но и сделать код взаимозависимым. Предположим сценарий, в котором вам нужно будет добавить несколько событий и состояний. Вместо того, чтобы писать и добавлять везде в коде, вы можете просто добавить в одном месте, и ваш код готов к расширению.!!