#c
Есть такой рабочий код: #include#define T 50 #define str(s) strk(s) #define strk(s) #s int main () { puts(str(T)); } Мы знаем что puts по прототипу не сможет вывести число, только строки. Я не понял, какую роль играют вот эти две строчки для вывода числа через подстановку (в нашем случае для T, вместо которого будет подставляться целое число) из puts: #define str(s) strk(s) #define strk(s) #s И зачем мы делаем подстановку к функции str(s) эту функцию strk(s) с произвольным именем (вместо str(s) и strk(s) можно писать что угодно и программа все равно заработает без ошибок)? Напоследок, что означает #s в данном примере?
Ответы
Ответ 1
Это такой хитрый способ заставить С рассматривать 50 не как число (и приводить к типу int), а как строку «50» (и превращать в последовательность байтов 0x30 0x35 0x00). Это делается как раз макросом с решеткой: #define strk(s) #s Решетка служит указанием — «рассматривай всю бурду, что попала в s, как строку». Убедитесь с помощью ideone. А этот макрос: #define str(s) strk(s) нужен для того, чтобы первая подстановка #define T 50 раскрылась и заменилась на 50. Если сразу сделать strk(T), программа превратит T в строку и напечатает «T». Это свойство можно использовать для формирования отладочного вывода: #define PRINT(A) printf(#A " = %d\n", A);Ответ 2
В дополнение. Посмотрим на это: #define T 50 #define str(s) #s int main() { puts( str(T) ); return 0; } Прогоним через препроцессор и получим: int main() { puts( "T" ); return 0; } То есть в таком варианте макрос str() будет превращать в строку не значение аргумента, а его имя :) Дополнтельный прогон через ещё один макрос и нужен потому, что в него попадёт уже именно значение (в нашем случае - 50).
Комментариев нет:
Отправить комментарий