Начнем с форматирования кода для размещения нескольких строк. Это нарушает тот факт, что это Куайн, но и делает его легче увидеть, что происходит:
char* s = "char*s=%c%s%c;main(){printf(s,34,s,34);}";
main() {
printf(s, 34, s, 34);
}
По сути, это декларация строки s
это printf
строку в формате, с последующим заявлением функции main
который вызывает printf
по четырем аргументам. (Это определение main
использует старомодное «неявное правило int
» в C, где предполагается, что функции имеют int
как возвращаемый тип, если не указано иное. Я считаю, что это в настоящее время не рекомендуется в C и точно знает, что это не является законным C++ код.)
Так что же это такое printf
позвонить? Ну, это могло бы помочь отметить, что 34 является ASCII код для двойной кавычки, так что линии
printf(s, 34, s, 34);
по существу
printf(s, '"', s, '"');
Это означает, что «напечатать строку s
с аргументами "
, s
, и "
. " Итак, что такое s
? Здесь показано здесь:
char* s = "char*s=%c%s%c;main(){printf(s,34,s,34);}";
Это следует за общим трюком самореференции. Игнорируя часть %c%s%c
, это в основном строковое представление остальной части программы. Часть %c%s%c
происходит в точке, где она становится самореференциальной.
Так что произойдет, если вы позвоните по телефону printf(s, '"', s, '"')
? Это заполнит заполнителем %c%s%c
с "char*s=%c%s%c;main(){printf(s,34,s,34);}"
, который является строковым содержимым строки s
. В сочетании с остальной частью строки s
, это поэтому proints
char*s="char*s=%c%s%c;main(){printf(s,34,s,34);}";main(){printf(s,34,s,34);";
который является исходным кодом программы. Я думаю, что это довольно аккуратно - самый близкий английский перевод общей программы Quine, которую я знаю, это «напечатать эту строку, второй раз в кавычках» (попробуйте - посмотрите, что произойдет!), И это в основном делает именно это.
Вы спрашивали, почему изменение чисел на 5 и 11 не изменилось, что было напечатано 34. Правильно! Строковый литерал s
имеет 34 жестко закодированных в нем, поэтому изменение 5 и 11 в вызове printf
не изменит это. То, что он будет делать, больше не печатает кавычки во внутренней части строки s
и вместо этого печатает непечатаемые символы.
Что он печатает после 'char * s =' и перед вторым '; main() {'?(где кавычки должны быть) – immibis
Что это связано с заголовком? – user2357112
'char * s =" blah ";' недопустим как код на C++. –