自我复制程序

Ani*_*rya 10 c linux printf ascii quine

main(a){printf(a="main(a){printf(a=%c%s%c,34,a,34);}",34,a,34);}
Run Code Online (Sandbox Code Playgroud)

编译后它是如何复制的?在printf函数中编写34的作用是什么?

Jas*_*n S 18

34是双引号(")字符的ASCII字符代码.


为了跟进我的切线评论(它是对Hofstadter的"Godel Escher Bach"的引用),这是有效的,因为它是一个quine,它基本上是一个包含两个元素的配方:数据内核和对该内核的操作,这样当操作完成时,再现原始配方.为此,内核和操作几乎完全相同.在你提到的程序中,内核是字符串

 "main(a){printf(a=%c%s%c,34,a,34);}"
Run Code Online (Sandbox Code Playgroud)

操作是程序的其余部分:

 main(a){printf(a=_____,34,a,34);}
Run Code Online (Sandbox Code Playgroud)

____内核在哪里 您会注意到它们看起来基本相同:操作可以通过使用内核作为格式说明符(打印内核但不加引号,从而将内核转换为输出中的操作)来打印自身,并将内核本身作为内容提供格式说明符(the %s)中的参数并引用它,从而在输出中产生内核.

operation(quoted kernel)=>不带引号的内核,包含内核的副本,quoted =>这是原始程序.


还有一点:它使用这个业务的原因是它通过使用没有引号字符的内核来保持引用操作的简单性; 如果你试图使用

"main(a){printf(a=\"%s\",a);}"
Run Code Online (Sandbox Code Playgroud)

作为内核,带有未加引号的内核

main(a){printf(a="%s",a);}
Run Code Online (Sandbox Code Playgroud)

这将更加困难,因为为了引用内核,你必须反斜杠 - 转义字符串中间的引号.

  • @Arya:这个页面对如何构建'quines'有一个很好的解释:http://www.madore.org/~david/computers/quine.html这可能会让你知道上面的工作原理. (2认同)