Использовать директиву #define preprocessor странным образом

#c #c-preprocessor #identifier

#c #c-препроцессор #идентификатор

Вопрос:

Сегодня я просто заканчиваю читать и экспериментировать на C о том, как использовать #define для создания константы манифеста, после этого мне кое-что пришло в голову, и ниже приведен код.

 #include <stdio.h>
#define dummy main
#define yam {
#define apple }

int dummy(void)        //constant substitution main with dummy
yam                          // constant substitution { with yam
  printf("It works!!n");
  return 0;
apple                           //constant substitution } with apple
  

Как и ожидалось, это работает как шарм, мне просто интересно, почему что-то подобное не вызвало никакой ошибки, может быть, я мог бы понять, почему main() можно заменить, потому что main это идентификатор (имя, присвоенное функции, переменной и константе), но почему {} можно заменить и символическим именем? Во-вторых, какой тип данных C использует для хранения этой символической константы, которая не является символом, заключенным в одинарные кавычки "" , ни целым числом или числом с плавающей запятой.

Комментарии:

1. Ради всего святого, не злоупотребляйте препроцессором такими ужасными способами!

2. хаха @Philip, мне просто любопытно, поэтому я сделал это, я не думаю, что я не собираюсь кодировать какое-либо программное обеспечение с помощью такого метода

3. Итак, в каком типе данных хранится текст { и}?? потому что я не заключил ее в одинарные кавычки

Ответ №1:

#define Инструкции оцениваются препроцессором перед фактической компиляцией программы, поэтому компилятор никогда не видит yam . Препроцессор выполняет прямую подстановку текста.

То есть, когда компилятор видит ваш код, он выглядит следующим образом:

 int main(void)        //constant substitution main with dummy
{                          // constant substitution { with yam
  printf("It works!!n");
  return 0;
}                           //constant substitution } with apple
  

Ответ №2:

Define — это буквально замена текста. На этапах препроцессора компилятор просмотрит ваш код и заменит все dummy на main , yam на { и apple на } .

Ответ №3:

Это работает, потому что препроцессор является * ПРЕДВАРИТЕЛЬНЫМ * процессором, то есть это то, что происходит перед реальной обработкой.

Таким образом, препроцессор выполняет свою грубую замену текста до того, как реальный компилятор посмотрит на код.

Ответ №4:

#define обрабатывается препроцессором. Материал будет заменен символ за символом до того, как компилятор скомпилирует код. По сути, вы можете скрыть весь свой код, используя #define но любой, у кого есть прекомпилятор, может отключить его позже. Препроцессор заменяет все вхождения определенной вами «константы», за исключением случаев, когда она заключена в кавычки (например, char *test="dumy yam apple"; останется неизменной).