自复制程序
main(a){printf(a="main(a){printf(a=%c%s%c,34,a,34);}",34,a,34);}
编译后它如何自我复制? printf函数中写34有什么作用?
main(a){printf(a="main(a){printf(a=%c%s%c,34,a,34);}",34,a,34);}
How it is reproducing itself after compilation? What is the role of writing 34 in printf function?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
34 是双引号 (") 字符的 ASCII 字符代码。
为了跟进我的离题评论(这是对 Hofstadter 的“Godel Escher Bach”的引用),这是有效的,因为它是一个 quine,基本上是一个包含两个元素:数据内核和该内核上的操作,以便在操作完成时重现原始配方,为此,内核和操作几乎与您提到的程序相同。内核是字符串
,操作是程序的其余部分:
其中
____
是内核,您会注意到它们看起来本质上是相同的:操作可以通过使用内核作为格式来打印自身。说明符(打印内核但不加引号,从而将内核转换为输出中的操作),并将内核本身作为格式说明符(%s
)中的参数提供并引用它,在输出中产生内核。操作(带引号的内核) => 不带引号的内核,包含内核的副本,带引号 =>这是原始程序。
还有一点:它使用这个 34 位业务的原因是它通过使用不带引号字符的内核来使引用操作变得容易;如果您尝试用作
内核,则使用不带引号的内核
会更加困难,因为为了引用内核,您必须对字符串中间的引号进行反斜杠转义。
34 is the ASCII character code for a double-quote (") character.
To follow up on my tangential comment (it was a reference to Hofstadter's "Godel Escher Bach"), this works because it's a quine, which is basically a recipe containing two elements: a kernel of data and an operation on that kernel, such that when the operation is complete the original recipe is reproduced. To do this, the kernel and the operation are almost identical. In the program you mention, the kernel is the string
and the operation is the rest of the program:
where
____
is the kernel. You'll note they look essentially the same: the operation can print itself by using the kernel as a format specifier (which prints the kernel but unquoted, thus transforming the kernel into the operation in the output), and also feeding the kernel itself as a parameter in the format specifier (the%s
) and quoting it, yielding the kernel in the output.operation(quoted kernel) => unquoted kernel that includes a copy of the kernel, quoted => which is the original program.
one more point: the reason it uses this 34 business is that it keeps the quoting operation easy by using a kernel without quote characters; if you tried to use
as the kernel, with an unquoted kernel of
it would be much more difficult because in order to quote the kernel, you'd have to backslash-escape the quotes in the middle of the string.