国际混乱C语言大赛获奖作品解析示例

国际混乱C语言大赛获奖作品解析示例

       国际混乱C语言大赛获奖的结果无疑是世界顶级C程序员C语言极限挖掘的结果。阅读,剖析它们绝对是一件超值的事情,下面我详细的剖析了一段在网上流传非常广的代码:

#i nclude <stdio.h> main(t,_,a)char *a;{return!0<t?t<3?main(-79,-13,a+main(-87,1-_, main(-86,0,a+1)+a)):1,t<_?main(t+1,_,a):3,main(-94,-27+t,a)&&t==2?_<13? main(2,_+1,"%s %d %d/n"):9:16:t<0?t<-72?main(_,t, "@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l+,/n{n+,/+#n+,/#/ ;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l / q#'+d'K#!/+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# / ){nl]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#n'wk nw' / iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c / ;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;#'rdq#w! nr'/ ') }+}{rl#'{n' ')# / }'+}##(!!/") :t<-50?_==*a?putchar(31[a]):main(-65,_,a+1):main((*a=='/')+t,_,a+1)   :0<t?main(2,2,"%s"):*a=='/'||main(0,main(-61,*a, "!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:/nuwloca-O;m.vpbks,fxntdCeghiry"),a+1);}

(IOCCC 1988年获奖作品,作者 Ian Phillipps。)

       以上是完整的源代码,编译运行之后会产生意想不到的优美输出,然后,大多数人直接阅读上面的代码相当吃力,以下我逐步将上述的代码解析成为了我们熟悉的形式。

       首先是去除干扰项,将其中的两个字符串置换为宏,便于下一步分析:

#define USER_STRING_L / "@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l+,/n{n+,/+#n+,/#/ ;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l / q#'+d'K#!/+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# / ){nl]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#n'wk nw' / iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c / ;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;#'rdq#w! nr'/ ') }+}{rl#'{n' ')# / }'+}##(!!/" #define USER_STRING_S / "!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:/nuwloca-O;m.vpbks,fxntdCeghiry"

接下来是关键语句的置换,思路是:

某一行出现两个以上条件运算符号的时候 按照熟悉的 if (a)  {} else  {} 格式 解析 (a)?(b):(c) 为 (a)?  (b) :  (c)

这样,

main(t,_,a)char *a; { return  !0<t?  (   t<3?main(-79,-13,a+main(-87,1-_,main(-86,0,a+1)+a)):1,   t<_?main(t+1,_,a):3,   main(-94,-27+t,a)&&t==2?   (    _<13?main(2,_+1,"%s %d %d/n"):9   )   :   (    16   )  )  :  (   t<0?   (    t<-72?    (     main(_,t,USER_STRING_L)    )    :    (     t<-50?     (      _==*a?putchar(31[a]):main(-65,_,a+1)     )     :     (       main((*a=='/')+t,_,a+1)     )    )   )   :   (    0<t?main(2,2,"%s"):*a=='/'||main(0,main(-61,*a,USER_STRING_S),a+1)   )  )  ; } 此时,代码的思路已经非常清晰了,但此函数在C语言级数上很难直接调试,相比于汇编级调试或者自己手动分析,再次转换代码是非常好的选择。 二次转换的核心思想如下: 将语句 return (a)?  (b) :  (c) 转换为 if (a) {  rnt = (b); } else {  rnt = (c); } 二次转换之后的代码如下:

main (t,_,a) char _; char *a; {  int rnt;  if (!0<t)  {   if (t<3)//t<3?main(-79,-13,a+main(-87,1-_,main(-86,0,a+1)+a)):1,   {    rnt = main(-79,-13,a+main(-87,1-_,main(-86,0,a+1)+a));   }else   {    rnt = 1;   }   if (t<_)//t<_?main(t+1,_,a):3,   {    rnt = main(t+1,_,a);   }else   {    rnt = 3;   }   if (main(-94,-27+t,a)&&t==2)   {//rnt = (_<13?main(2,_+1,"%s %d %d/n"):9);    if (_<13)    {     rnt = main(2,_+1,"%s %d %d/n");    }else    {     rnt = 9;    }   }else   {    rnt = 16;   }  }else  {   if (t<0)   {    if (t<-72)    {     rnt = main(_,t,USER_STRING_L);    }else    {     if (t<-50)     {      if (_==*a)      {       rnt = putchar(31[a]);      }else      {       rnt = main(-65,_,a+1);      }     }else     {      rnt = main((*a=='/')+t,_,a+1);     }    }   }else   {//0<t?main(2,2,"%s"):*a=='/'||main(0,main(-61,*a,USER_STRING_S),a+1);    if (0<t)    {     rnt = main(2,2,"%s");    }else    {     rnt = (*a=='/'||main(0,main(-61,*a,USER_STRING_S),a+1));    }   }  }  return rnt; } 到这里,你就可以单步调试来好好品位你这段代码了。

说明:

    文中的代码(源代码,剖析后代码)均可运行,我自己使用的编译环境是VC6.0。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值