@ предложение Лундина, чтобы использовать перечисления делает для очень эффективного кода, но я обнаружил, что метод трудно поддерживать, как только списки выходят за пределы половины страницы или около того. Именно поэтому я приспособил этот метод:
#define TAG_MAP { \
_MAP(TAG_BODY,"body"), \
_MAP(TAG_HEAD,"head"), \
_MAP(TAG_HTML,"html"), \
_MAP(TAG_UNKNOWN,"unknown"), \
}
#define _MAP(x,y) x
enum tags TAG_MAP;
#undef _MAP
#define _MAP(x,y) y
const char *tagstrings[] = TAG_MAP;
#undef _MAP
//usage: printf("%s\n",tagstrings[TAG_HTML]);
Этот метод может быть использован для инициализации data[]
непосредственно, которая в основном более эффективный вариант того, что макро-версия for(;;)
цикла будет делать (вы не можете разыменовать значение переменной для вставки в макрос)
Это может быть распространено на столько элементов любого типа, сколько вам нравится, и даже на несколько аргументов (если вы их поместили последними и используете ,...
и __VA_ARGS__
) Я часто использую его для сохраните отсортированный список, который может разрешить перечисление, используя быстрый двоичный поиск, а затем использовать это значение для различных таблиц поиска.
Для более сложного примера, который использует макросы только, а также использует va_args см my quixotic libc Все архитектуры зависит материал определяется на 1 линии и различные директивы препроцессора переводящих п-й аргумент соответствующего определения. Syscalls использует другой вид хака для вызова sycall0 ... syscall6 в зависимости от количества переданных аргументов.
«Определенные значения выше» - № Это макроопределения. – Olaf
Неясно, что вы имеете в виду. И почему бы просто не использовать макросы напрямую? Слишком очевидно? Слишком читаемо? Слишком короткий, чтобы писать? – Olaf
'MakeDefinitionA (n);' препроцессор не может использовать (оценивать) переменную времени выполнения. – BLUEPIXY