我越是试图理解这个令人困惑的谜团,我就越想放弃。
char *s = "char *s = %c%s%c; main(){printf(s,34,s,34);}"; main(){printf(s,34,s,34);}
当程序执行时,这个单行源代码是如何产生完全相同的输出的,这种程序有什么共同的概念吗?
This is called a Quine.
So let's see what main()
does:
printf(s,34,s,34);
34 is the ASCII code for the character "
(double quote), so this is the same as:
printf(s, '"', s, '"');
The first argument to printf(3)
is the format string. The string passed is:
"char *s = %c%s%c; main(){printf(s,34,s,34);}"
So, printf(3)
will output exactly that, but note the %c
, %s
and %c
format specifiers, which instruct printf(3)
to print a character, followed by a string, followed by another character in that place, which are respectively the 2nd, 3rd and 4th arguments.
The characters, as we saw, are both "
, and the string is s
again (the same string). So the program output is:
char *s = "X"; main(){printf(s,34,s,34);}
Where X
is the string s
in the program. So we get this as output:
char *s = "char *s = %c%s%c; main(){printf(s,34,s,34);}"; main(){printf(s,34,s,34);}
Which, interestingly, is the program source itself.
从 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);}'
要理解代码,首先简化并重新格式化:
char *s = "some format string";
main() {
printf(s,34,s,34);
}
因此它s
用作格式化字符串来打印三个实体:34
、字符串s
本身和34
. 在这种情况下,格式化字符串的重要部分s
是:
char *s = "... %c%s%c ..."
这意味着两个34
s 变成双引号 ( "
) 并且格式化字符串s
只是作为普通字符串打印。现在您应该看到格式化字符串的其余部分s
只是整个程序的副本。