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 , 还假设了双引号 " 的值为 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++等等。