小议国际C语言混乱代码大赛——附87年一行的代码分析
来源:互联网 发布:合肥启凡网络怎么样 编辑:程序博客网 时间:2024/05/02 02:22
一年前的这个季节看的时候,网上还是停留着06年的信息,还以为就此结束了,今天突然在CSDN首页看到居然更新两期了,围观下大牛们的杰作。
虽然在现实中,我们不可能写出那样的代码,其主要的原因是不方便阅读,而且难以维护,但一行代码中可以学习的东西可能比我们翻半天书的还多,比如下的一行代码就能学到平时很难学到的东西:
printf(&unix["\021%siz\012\0"], (unix)["have"] + "fun" - 0x60);
这行代码是1987年 贝尔实验室的 David Korn 提交了这个获奖作品。
当然我们平时写作是用不到这么高深的东西,但经过如下分解后,这些知识点我们都是否能掌握呢?
如果以上代码在windows平台是不能直接运行的,可以再定义一下:
#define unix 1
在C语言中,数组的引用除了我们常用的 array[num],还可以是num[array],两者是相同。
所以(unix)["have"] 等于"have"[unix],前面unix定义为1,这里的结果就是have中下标为1的那个字符a。
针对这样的式子:"a" + "fun" - 0x60,再作一次变换,0x61-0x60+"fun",加减交换,小学就学过的,不用解释了吧,十六进制0x61 = 十进制97,正好是小写字母a的ASCII码。
上面式子自然变成了0x01+"fun",一个字符串地址加上一位后会是什么样的呢?这样还不明白的话,把fun当成指针里存的数据来是不是容易理解了呢,如*prt++后的结果“un”,这样就更容易明白了吧。
\012 是ASCII码里的换页.功能与\n相同。
再前面一个%s,打印字符串不作解释。
上面已经说到 array[num]等价num[array]
&unix["\021%siz\012\0"], 再简化一下,&1["\021%siz\n\0"],这里需要把\021处理成一个字符,ASCII码里021是什么也不重要了,我们只把这个转义字符处理成一个就行了,所以这个串理解为:
"\021%siz\012\0" [1]等于"\021%siz\n\0" [1]等于"%siz\n\0"
整个语句就化解为:printf("%siz\n\0","un");其中\0是一个(空),已经不重要了,分析到这里,应该明白这个语句输出的是什么了吧!
You Got It:uniz
分析了这么多,现在明白了,其实原理也是那么简单,当我们第一眼没看出来结果的时候,我们是不是应该觉得有必要复习一下了呢?
- 小议国际C语言混乱代码大赛——附87年一行的代码分析
- 1987年国际C语言混乱代码大赛获奖的一行代码
- 1987年国际C语言混乱代码大赛获奖的一行代码
- 国际C语言混乱代码大赛作品分析!
- 国际C语言混乱代码大赛作品分析!
- 国际C语言混乱代码大赛
- 国际C语言混乱代码大赛:IOCCC
- 国际C语言混乱代码大赛
- 2012国际C语言混乱代码大赛冠军代码
- 国际C语言混乱代码大赛代码赏析(一)
- 国际C语言混乱代码大赛代码赏析(一)
- 国际C语言混乱代码大赛代码赏析
- 国际C语言混乱代码大赛(IOCCC)
- 国际C语言混乱代码大赛结果公布
- 第二十一届国际C语言混乱代码大赛结果公布
- 国际C语言混乱代码大赛结果公布
- 国际C语言混乱代码大赛----1988获奖作品赏析
- 第21届国际C语言混乱代码大赛获奖作品
- GCC学习笔记(1)
- 2012年10月份,百度笔试题
- win7 64 配置NGINX和PHP部署
- Tomcat自动更新
- 磁珠和磁环
- 小议国际C语言混乱代码大赛——附87年一行的代码分析
- JM8.6中看起来让人不寒而栗的 int ******究竟是怎么回事?
- 便宜5万
- Linux网络编程之tcpdump抓包分析TCP三次握手过程
- Web服务器Tomcat配置
- c#
- java常量池概念
- Eclipse自动补全增强
- java中==号和equals的比较