Проработав более 10 лет, сегодня мне на глаза попался код, я не могу понять, как имя функции, определенное внутри функции, печатается в выводе/журнале, не будучи переданным в качестве аргумента в макросе или определяемым как глобальная переменная. Помогите, пожалуйста, разобраться во внутреннем. Пожалуйста, смотрите скриншот для справки.
/*...*/
#include <stdio.h>
#define x printf("%s", f);
int main() {
char *f = "MAIN";
printf("Hello World");
x;
return 0;
}
Вывод:
Hello WorldMAIN
1) Пожалуйста, НЕ размещайте изображения; скопируйте/вставьте свой код как ТЕКСТ. 2) почитайте о макросах C: #define. Все, что он делает, это «заменяет текст». 3) В частности, везде, где препроцессор C увидит «x», он заменит текст printf("%s", f);, прежде чем передать его компилятору. 4) Этот конкретный макрос ПЛОХОЙ... по многим-многим причинам. Пожалуйста, рассмотрите возможность избавиться от него!
большой или маленький, это не имеет значения. У вас более 11 тысяч репутации, и вы все еще делаете эту глупость? Почему нельзя загружать изображения кода/данных/ошибок?





Макросы препроцессора C просто выполняют замену текста. У них нет семантической осведомленности о вашей программе.
Этот:
#include <stdio.h>
#define x printf("%s", f);
int main()
{
char* f = "MAIN";
printf ("Hello World");
x;
return 0;
}
Становится:
#include <stdio.h>
int main()
{
char* f = "MAIN";
printf ("Hello World");
printf("%s", f);;
return 0;
}
Обратите внимание, что если при использовании этого макроса не объявлено f, вы увидите ошибку компилятора. Если f объявлен, но не является char *, вы должны увидеть предупреждения компилятора.
Некоторые лучшие практики макросов препроцессора включают (но не ограничиваются) использование имен с заглавными буквами, поскольку x по соглашению выглядит как имя переменной или функции; и будьте осторожны с тем, какие синтаксически значимые символы (в данном случае ;) вы включаете в свой текст макроса.
Надеюсь, этот пример был сделан для обучения, потому что он совершенно не нужен. Макросы препроцессора не существовали бы, если бы они не служили цели, но имейте в виду, что они могут легко запутать код.
Спасибо за отличное объяснение и за указание на некоторые проблемы в примере макроса OP. Макросы могут быть чрезвычайно полезными. Но макрос ОП — отличный пример того, как НЕ использовать макросы. Это программный ужас.
Макросы препроцессора — это просто замена текста. Все операторы #include заменяются содержимым указанных файлов. Все вхождения символов #define'd заменяются их указанным текстом. Все комментарии опущены. Так далее...
Итак, в вашем примере:
/*...*/
#include <stdio.h>
#define x printf("%s", f);
int main() {
char *f = "MAIN";
printf("Hello World");
x;
return 0;
}
Препроцессор заменяет все экземпляры x текстом printf("%s", f); перед тем, как обработанный код будет отправлен компилятору. Итак, вот код, который на самом деле видит компилятор:
// contents of <stdio.h> here...
int main() {
char *f = "MAIN";
printf("Hello World");
printf("%s", f);;
return 0;
}
Пожалуйста, не размещайте изображения кода. Пожалуйста, отправьте код в виде текста.