IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

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

    longhao (longtask@gmail.com)发表于 2010-05-11 05:35:53
    love 0

         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++等等。



沪ICP备19023445号-2号
友情链接