求1988年国际C语言乱码大赛获奖程序分析,作者是Ian Phillipps

Python013

求1988年国际C语言乱码大赛获奖程序分析,作者是Ian Phillipps,第1张

不要再问我,我是转贴滴。。。。。。

// 编译环境main入口,CRTO.C for main(__argc, __argv, _environ)

// 方法的编译原来,返回值的寄存器状态

// 变量的类型转换reinterpret_cast

// 使用一个新的main方法,将旧的用一个新方法'decode'表示

// 根据题设,本程序执行方式为无命令参数,即,argc==1

// 变量的声名规约,改变变量名以方便理解

// 进一步重构if语句

#include <stdio.h>

int decode(int arg1,int arg2,char* sCodec){

if(1<arg1){

if(arg1<3)

decode(-79,-13,sCodec+decode(-87,1-arg2,decode(-86,0,sCodec+1)+sCodec))

if(arg1<arg2)

decode(arg1+1,arg2,sCodec)

if(decode(-94,-27+arg1,sCodec)&&arg1==2){

// 内部递归,无后续分支,可展平为递推方式

if(arg2<13)

return decode(2,arg2+1,"%s %d %d\n")

else

return 9

}else

return 16

}else if(arg1<-72){

// 可根据arg1范围代入。本条件代入后略

return decode(arg2,arg1,"@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#'ldr'}{nlwb!/*de}'c {nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+#'rdq#w! nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/")

}else if(arg1<-50){

// 内部递归,无后续分支,可展平为递推方式

if(arg2==*sCodec)

return putchar(sCodec[31])

else

return decode(-65,arg2,sCodec+1)

}else if(arg1<0){

// 内部递归,无后续分支,可展平为递推方式

return decode((*sCodec=='/')+arg1,arg2,sCodec+1)

}else if(0<arg1){ // arg1 == 1,初始情况,根据arg1取值取舍

return decode(2,2,"%s")

}else{ // arg1 == 0

if(!(*sCodec=='/'))

// 内部递归,无后续分支,可展平为递推方式

return decode(0,decode(-61,*sCodec,"!ekdc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-Om .vpbks,fxntdCeghiry"),sCodec+1)

else

return 1

}

}

int main(int argc, char* argv[], char** _environ){

return decode(argc,(int)argv,(char*)_environ)

}

// 分析出递归顶层返回值。

// 注意所有return的含义,9/16/1/putchar(),Non Zero ->TRUE

// 分析arg1的内容,重构方法,有些坳,自己试着理解吧

#include <stdio.h>

int decode(int arg1,int arg2,char* sCodec){

if(1<arg1){

if(arg1<3){

decode(0,-86,"@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#'ldr'}{nlwb!/*de}'c {nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+#'rdq#w! nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/")

decode(1-arg2,-87,"@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#'ldr'}{nlwb!/*de}'c {nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+#'rdq#w! nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/")

decode(-13,-79,"@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#'ldr'}{nlwb!/*de}'c {nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+#'rdq#w! nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/")

}

if(arg1<arg2)

decode(arg1+1,arg2,sCodec)

decode(-27+arg1,-94,"@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#'ldr'}{nlwb!/*de}'c {nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+#'rdq#w! nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/")

if(arg1==2){

while(arg2<13){

arg2 ++

sCodec = "%s %d %d\n"

// 上方条件代入

if(arg1<3){

decode(0,-86,"@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#'ldr'}{nlwb!/*de}'c {nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+#'rdq#w! nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/")

decode(1-arg2,-87,"@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#'ldr'}{nlwb!/*de}'c {nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+#'rdq#w! nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/")

decode(-13,-79,"@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#'ldr'}{nlwb!/*de}'c {nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+#'rdq#w! nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/")

}

if(arg1<arg2)

decode(arg1+1,arg2,sCodec)

decode(-27+arg1,-94,"@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#'ldr'}{nlwb!/*de}'c {nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+#'rdq#w! nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/")

}

}

}else if(arg1<-50){

// 判断条件可达,取舍

char* s = sCodec

while(!(arg2==*s)){

s ++

}

putchar(s[31])

}else if(arg1<0){

for(arg1<0arg1+=(*sCodec=='/'))

sCodec ++

decode(0,arg2,sCodec+1)// 条件合并

}else if(arg1 == 0){

while(!(*sCodec=='/')){

// 条件合并

decode(-61,*sCodec,"!ekdc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-Om .vpbks,fxntdCeghiry")

sCodec ++

}

}

return 1// return TRUE only

}

int main(int argc, char* argv[], char** _environ){

decode(2,2,"%s")

return 9

}

"\33[60H\33[K"

首先, 两个 \33 是C语言的转义字符表示, 33是8进制, 也就是ASCII为27的那个字符,

这字符表示换码, 有的地方写作 ESC (见ASCII表)

当这个字符串用在 printf中的时候,

输出到屏幕表示对屏幕的控制, 比如改变背景或者文字颜色等.

这个格式和含义都是标准的终端的.

就上面的例子, 实际是两个控制命令:

ESC[60H将光标移动到第6行的行首

ESC[K 清除从光标到行尾的内容

这个在Linux下有效. 在WINDOWS的控制台窗口是用Console Functions来控制屏幕属性.

参考 Linux终端ANSI控制码, VT100/ANSI 控制字符

如果真正掌握了C 语言,你就能很轻易的回答上来。这个问题就请读者试着回答一下吧。本章不会像关键字一样一个一个深入讨论,只是将容易出错的地方讨论一下。

表(2.1)标准C 语言的基本符号

C 语言的基本符号就有20 多个,每个符号可能同时具有多重含义,而且这些符号之间相互组合又使得C 语言中的符号变得更加复杂起来。

你也许听说过“国际C 语言乱码大赛(IOCCC)”,能获奖的人毫无疑问是世界顶级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#'ldr'}{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,"!ekdc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-Om.vpbks,fxntdCeghiry"),a+1)}

还没发狂?看来你抵抗力够强的。这是IOCCC 1988 年获奖作品,作者是Ian Phillipps。

毫无疑问,Ian Phillipps 是世界上最顶级的C 语言程序员之一。你可以数数这里面用了多少个符号。当然这里我并不会讨论这段代码,也并不是鼓励你也去写这样的代码(关于这段代码的分析,你可以上网查询)。