程序源代码与其输出完全相同

时间:2015-08-28 09:26:39

标签: c printf output quine

我越想了解这个困惑的谜,我就越想放弃。

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

这个单行源代码如何在程序执行时生成完全相同的输出,这种程序有什么常见的概念吗?

3 个答案:

答案 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 只是整个程序的副本。