国际混乱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。

 

以上文字转自http://blog.21ic.com/user1/3664/archives/2008/47138.html

 

对解析的过程及其思路,比较欣赏

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值