您的位置:首页 > 编程语言 > C语言/C++

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

2010-07-21 11:36 489 查看
国际混乱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 *%n+r3#l,{}:/nuwloca-O;m]*%n+r3#l,{}:/nuwloca-O;m.vpbks,fxntdCeghiry"),a+1]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 *%n+r3#l,{}:/nuwloca-O;m]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

对解析的过程及其思路,比较欣赏
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: