2015-08-28 3 views
8

Чем больше я пытаюсь понять эту озадаченную загадку, тем больше хочу сдаться.Программа, исходный код которой точно такой же, как и ее вывод

char *s = "char *s = %c%s%c; main(){printf(s,34,s,34);}"; main(){printf(s,34,s,34);} 

Как происходят для этого одной строки исходного кода, чтобы генерировать точно такой же вывод, когда программа выполняется, и есть какое-либо общее понятие для такого рода программ?

+2

Знаете ли вы, что делает 'printf'? Вы можете определить, что 'printf (" char * s =% c% s% c; main() {printf (s, 34, s, 34);} ", 34," char * s =% c% s% c; main() {printf (s, 34, s, 34);} ", 34)' печатает, учитывая, что 34 является кодом ASCII для '' '? – immibis

+0

Теперь это официально - мне ужасно не хватает навыков анализа – Malina

+0

Я знаю, что такое 34 и что делает printf .. это просто семантически меня смущает. – Malina

ответ

11

Это называется Quine.

Итак, давайте посмотрим, что main() делает:

printf(s,34,s,34); 

34 является ASCII код символа " (двойные кавычки), так это то же самое, как:

printf(s, '"', s, '"'); 

Первый аргумент в printf(3) - это строка формата. Строка, передаваемая является:

"char *s = %c%s%c; main(){printf(s,34,s,34);}" 

Так, printf(3) будет выводить точно, но обратите внимание на спецификатор %c, %s и %c формата, которые инструктируют printf(3) напечатать символ, за которым следует строка, а затем еще один символ в том, что место, которые являются соответственно 2-м, 3-м и 4-м аргументами.

Символы, как мы видели, являются как ", так и строка s (эта же строка). Таким образом, выход программы:

char *s = "X"; main(){printf(s,34,s,34);} 

Где X это строка s в программе. Таким образом, мы получаем это как выход:

char *s = "char *s = %c%s%c; main(){printf(s,34,s,34);}"; main(){printf(s,34,s,34);} 

Какой, интересно, сам источник программы.

+0

Неизбежно объяснительно-обфускация, поэтому я думаю, что не дать это студентам - замечательная идея. Спасибо :) – Malina

+1

@Malina Действительно, это может быть сложным для неподготовленного студенческого глаза, но саморепликационные программы являются важной частью теории вычислимости. Студенты должны, по крайней мере, изучить концепцию. –

+0

Я также обновил вопрос, чтобы сделать его более ценным для других, читающих ваш ответ параллельно с добавлением. – Malina

3

взять эту строку из первого параметра Printf:

'char *s = %c%s%c; main(){printf(s,34,s,34);}' 

и сделать замену, где

%c = 34 = '"' //(same for both %c) 
%s = 'char *s = %c%s%c; main(){printf(s,34,s,34);}' 

Printf будет делать замену только один раз (не рекурсивный), поэтому результат:

'char *s = "char *s = %c%s%c; main(){printf(s,34,s,34);}"; main(){printf(s,34,s,34);}' 
1

Чтобы понять код, сначала упростить и переформатирование:

char *s = "some format string"; 
main() { 
    printf(s,34,s,34); 
} 

поэтому он использует s в виде строки форматирования для печати три объекта: 34, строка s себя и 34. В этом случае важная часть строки форматирования s является:

char *s = "... %c%s%c ..." 

что означает две 34 ые стали двойные кавычки (") и форматирование-строку s только печатается в виде обычной строки.Теперь вы должны увидеть rest форматирующей строки s - это всего лишь копия всей программы.

 Смежные вопросы

  • Нет связанных вопросов^_^