为什么Ken Thompson在“C”中提到了这个奎因;关于信任的思考;不工作?

为什么Ken Thompson在“C”中提到了这个奎因;关于信任的思考;不工作?,c,quine,C,Quine,我在Ken Thompson(read)的一篇文章中看到的这个quine并没有复制相同的代码。我只是好奇为什么它不起作用?代码现在过时了吗 奎因代码: char s[] = { '\t', '0', '\n', '}', ';', '\n', '\n', '/', '*', '\n' }; /* *The string s is a

我在Ken Thompson(read)的一篇文章中看到的这个quine并没有复制相同的代码。我只是好奇为什么它不起作用?代码现在过时了吗

奎因代码:

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>