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

Program which source code is exactly the same as its output

我越想弄明白这个令人困惑的谜,就越想放弃。

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

这种一行源代码怎么会在程序执行时生成完全相同的输出,这种程序有什么共同的概念吗?

从 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);}'

这叫做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);}

有趣的是,这是程序源本身。

要理解代码,首先简化并重新格式化:

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

所以它使用 s 作为格式化字符串来打印三个实体:34、字符串 s 本身和 34。在这种情况下,格式化字符串 s 的重要部分是:

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

这意味着两个 34 变成双引号 (") 并且格式化字符串 s 只是作为普通字符串打印。现在您应该看到格式化字符串 srest 只是整个程序的副本。