β

Ken Thompson的经典命题:输出自身源代码的程序(c,python,java)

龙浩的blog 150 阅读

Ken Thompson (C语言和Unix的发明者之一,目前在google搞go语言)在获得图灵奖的演说中提到:读大学的时候他曾经写出一个 输出自身代码的程序 (没有游戏的时代就只能玩YY了,自己出题自己做)。那个时候还没有C,python,java,实现这个问题的难度在于引用和字符串,当然也有多种经典的解法。

C语言

经典的例子 (应该以一行表示的, 虽然第一次执行后它后自我 修复):

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

这段程序有一些依赖, 忽略了 #include <stdio.h>, 还假设了双引号 " 的值为 34, 和 ASCII 中的值一样。

还有一个由 James Hu 发布的改进版:

#define q(k)main(){return!puts(#k"\nq("#k")");}
q(#define q(k)main(){return!puts(#k"\nq("#k")");})

Python版本

解法一:

a = "print 'a = ', repr(a), '\n', repr(a)[1:-5]', a"
print 'a = ', repr(a), '\n', repr(a)[1:-5]

解法二:

a = ["print 'a = ', a, '\\n', ''.join(a)"]
print 'a = ', a, '\n', ''.join(a)

Java版本

应该考虑在一行搞定,去掉包的申明,这样实现起来就简单多了。

class S{public static void main(String[]a){String s="class S{public static void main(String[]a){String s=;char c=34;System.out.println(s.substring(0,52)+c+s+c+s.substring(52));}}";char c=34;System.out.println(s.substring(0,52)+c+s+c+s.substring(52));}}

其他语言实现起来应该也很简单,大家可以尝试用不同语言继续实现。例如:C#,ruby,C++等等。