为什么Ken Thompson在“C”中提到了这个奎因;关于信任的思考;不工作?
我在Ken Thompson(read)的一篇文章中看到的这个quine并没有复制相同的代码。我只是好奇为什么它不起作用?代码现在过时了吗 奎因代码:为什么Ken Thompson在“C”中提到了这个奎因;关于信任的思考;不工作?,c,quine,C,Quine,我在Ken Thompson(read)的一篇文章中看到的这个quine并没有复制相同的代码。我只是好奇为什么它不起作用?代码现在过时了吗 奎因代码: char s[] = { '\t', '0', '\n', '}', ';', '\n', '\n', '/', '*', '\n' }; /* *The string s is a
char s[] = {
'\t',
'0',
'\n',
'}',
';',
'\n',
'\n',
'/',
'*',
'\n'
};
/*
*The string s is a representation of the body
*of this program from '0'
* to the end
*/
main(){
int i;
printf("char\ts[] = {\n");
for(i = 0; s[i]; i++)
printf("\t%d, \n", s[i]);
printf("%s",s);
}
输出:
char s[] = {
9,
48,
10,
125,
59,
10,
10,
47,
42,
10,
0
};
/*
以下是编译时的编译器警告(self\u reproading.c
是文件名):
self_reproading.c:20:1:警告:返回类型默认为'int'[-Wimplicit int]
20 | main(){
| ^~~~
c:在函数“main”中:
自我复制。c:23:2:警告:函数“printf”的隐式声明[-Wimplicit函数声明]
23 | printf(“char\ts[]={\n”);
| ^~~~~~
自我复制。c:23:2:警告:内置函数“printf”的隐式声明不兼容
自我复制。c:1:1:注意:包括“”或提供“printf”声明
+++|+#包括
1 | char s[]={
哎呀!我忽略了删除的
213行。所以问题应该是-文章中提到的整个奎因是什么?您很可能没有包括“”库
加上
#include <stdio.h>
#包括
在你的代码之上
在您的编译器错误中建议使用相同的解决方案,我认为“不工作”的意思是不“给编译器警告”-因为这些原因是不言而喻的-而是您写的其他内容:
这个奎因[…]没有复制相同的代码
奎因是自我复制的,一旦我们添加回作者删节并被您删除的(删除213行)
,它代表代码的其余部分,加上结束字符数组的0
NUL终止符:
/*
*字符串s是主体的表示形式
*从“0”删除此程序的
*到底
*/
您的困惑似乎源于程序如何打印所述数组中字符的ASCII整数值,但它最初声明了这些字符,如'\t'
,'\n'
,等等。但是具有适当值的整数是有效的char
s,因此代码是自复制的,即使元素是格式化的d作为整数,而不是原始源代码中的'c'
字符。无论哪种方式,我们最终得到一个相同字符的数组;只是该数组以不同但等效的方式初始化
为什么它要把它们打印成整数?因为这比每个元素都必须引用、有条件地转义等要容易得多/短得多。它映射到相同的机器代码/数组内容,但编程quine所需的faff要少得多
作者甚至写了这个
(纯粹主义者会注意到,该程序并不完全是一个自复制程序,而是会产生一个自复制程序。)
至于编辑/添加的问题,整个quine当然会添加表示程序其余部分所需的其他字符。作者大概是为了能够更容易地说明他们的观点而对程序进行了删节,而不必通过整页来将其带回家
“我在Ken Thompson(read)的一篇文章中看到的这个quine并没有复制相同的代码。我只是好奇为什么它不起作用?”
它没有给出预期的输出,因为它不是“奎因”的可复制示例
引用肯自己对“奎因”的定义(强调我的定义):
“更确切地说,问题在于编写一个源程序,当编译和执行时,将生成源程序的精确副本作为输出。”
显示的代码没有将整个源代码的精确副本复制为输出,因为它并不打算复制
肯甚至承认自己(强调我的):
图1显示了C编程语言中的一个自复制程序。(纯粹主义者会注意到,该程序并不完全是一个自复制程序,而是会产生一个自复制程序。)这篇文章太大,无法获奖,但它展示了这项技术,并且有两个重要特性,我需要它们来完成我的故事:…”
肯的代码中删除的213行也证明了这一点
它只是为了演示“quine”程序应该是什么,其目的是打印其源代码
“代码现在过时了吗?”
除了代码缺少部分之外,将其归类为严格的“quine”
是的,这个代码现在已经过时了。它是在1984年产生的,当时C甚至还没有被ANSI标准化,它是为一台完全不同的机器而编写的,就像我们现在拥有的机器一样
你收到的警告证明了这一点
要在没有警告的情况下编译此代码并包含头文件stdio.h
,您需要一个编译器(或适当的编译器选项,如f.e.std=c89
),该编译器支持printf()
函数的隐式声明,该函数自C99(当前标准为C18)以来不再受支持
请注意,编译器/链接器可能仍然会正确链接到printf()
的定义,但这是一个过时的功能,不符合现代标准
此外,main()
符号不再受支持。如果未向main()
传递任何参数,则该符号应为严格符合标准的int main(void)
,或者至少为int main()
提供原型,因此不推荐使用该符号
*返回类型可以不同,但必须与int
兼容
“文章中提到的整个奎因是什么?”
这只是一个“奎因”的例子。没有完整的原始例子公开。也许原始的睡在任何地方的档案。但y
#include <stdio.h>