8

我越是试图理解这个令人困惑的谜团,我就越想放弃。

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

当程序执行时,这个单行源代码是如何产生完全相同的输出的,这种程序有什么共同的概念吗?

4

3 回答 3

11

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.

于 2015-08-28T09:40:34.527 回答
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);}'
于 2015-08-28T09:40:03.727 回答
1

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

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

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

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

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

于 2015-08-28T09:45:06.753 回答