我越想了解这个困惑的谜,我就越想放弃。
char *s = "char *s = %c%s%c; main(){printf(s,34,s,34);}"; main(){printf(s,34,s,34);}
这个单行源代码如何在程序执行时生成完全相同的输出,这种程序有什么常见的概念吗?
答案 0 :(得分: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);}
有趣的是,这是程序源本身。
答案 1 :(得分: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);}'
答案 2 :(得分:1)
要理解代码,首先要简化并重新格式化:
char *s = "some format string";
main() {
printf(s,34,s,34);
}
因此它使用s
作为格式字符串来打印三个实体:34
,字符串s
本身和34
。在这种情况下,格式字符串s
的重要部分是:
char *s = "... %c%s%c ..."
表示两个34
成为双引号("
),格式字符串s
只是作为普通字符串打印。现在您应该看到格式化字符串s
的 rest 只是整个程序的副本。