C 语言奎因程序示例

x89*_*x89 0 c quine

在我的课程幻灯片中,我有这个例子,但没有太多解释:

char*f="char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c";main(){printf(f,34,f,34,10);}
Run Code Online (Sandbox Code Playgroud)

我理解quine 程序的一般含义,但我不太明白上面的代码中发生了什么。这是我运行它时得到的输出:

char*f="char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c";main(){printf(f,34,f,34,10);}
Run Code Online (Sandbox Code Playgroud)

但它如何复制自己的代码呢?我真的不明白输出是如何产生的。

Edd*_*lis 5

首先以更清晰的方式写出来(除了布局之外不改变任何内容):

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

main()
{
    printf(f,34,f,34,10);
}
Run Code Online (Sandbox Code Playgroud)

所以我们看到了一个main我们所期望的函数(它应该返回一个int,但你可以在 C 中使用 not ;同样对于没有函数参数的情况)。在此之前,是一个常规字符串。这是一个看起来很有趣的字符串,但它与char*f="fish";.

好吧,如果我们printf手动将字符串放入其中来扩展 会怎么样?

printf("char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c" ,34,f,34,10);
Run Code Online (Sandbox Code Playgroud)

我们可以看到它将打印出一些废话,并在此过程中替换一些值。他们是:

 First %c : 34   (the ASCII code for " (quotes))
 First %s : 'f'  (our string, once again)
Second %c : 34   (" again) 
 Third %c : 10   (the ASCII code for Newline)
Run Code Online (Sandbox Code Playgroud)

让我们也将这些全部替换为 then (尽管我已将字符串的内容替换为<the string>, 和"' \",以使其实际上作为独立语句工作):

main()
{
    printf("char*f=\"<the string>\";main(){printf(f,34,f,34,10);}\n");
}
Run Code Online (Sandbox Code Playgroud)

好吧,看看那个! main只是打印出我们首先开始的行。欢呼!


编辑添加:

虽然我已经基本为你说出了答案,但仍然有一个谜题。自己考虑一下为什么我们要费心在 中进行替换34, f, 34, 10,而不是像我在最终代码中那样将它们直接放入字符串中。