ioccc代码分析(1)

本文探讨了IOCCC(国际混乱C语言代码大赛)中的一个代码实例,通过格式化和分析,揭示了代码背后的逻辑。作者解释了C语言中数组的等价表示,并逐步解读了代码的for循环和write函数的用途,指出该程序实际上是在屏幕上输出数组b的内容。通过对write函数的说明,明确了其在输出字符到屏幕上的作用。

在四级考试的前一天,咸鱼的我不仅没有学英语,还开始研究起了IOCCC(国际混乱C语言代码大赛)。个人C语言学的也比较渣,在看了这些大神的代码之后,更加感觉自己C语言都学狗身上去了,先看第一个代码:

int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\
o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}

初看太乱,先用devc格式化一下,再加上头文件返回值

#include <stdio.h>
int i;
int main()
{
	for(; i["]<i;++i){--i;}"]; read('-'-'-',i+++"hell\
o, world!\n",'/'/'/'));
	return 0;
}
void read(j,i,p)
{
	write(j/p+p,i---j,i/i);
}

显然for循环那一排最后那个反斜杠只是用来换行写而已。再把字符串用字符数组替换,对程序的运行应该是没有影响的

#include <stdio.h>
int i;
int main()
{
	char a[]="]<i;++i){--i;}";
	char b[]="hello, world!\n";
	for(; i[a]; read('-'-'-',i+++b,'/'/'/'));
	return 0;
}
void read(j,i,p)
{
	write(j/p+p,i---j,i/i);
}

好像差不多能看懂了?不过i[a]是什么东西?这就要提到C语言的一个特性了,a[b] 与 b[a]等价,所以 i[a] 可以替换成 a[i],看来这里只是一个普通的取数组内容而已啊。我们再分析一下read函数的三个参数,可以看到 '-'-'-' 的值恒等于0,'/'/'/'值等于1,既然如此,我们再把代码更新一下

#include <stdio.h>
int i;
int main()
{
	char a[]="]<i;++i){--i;}";
	char b[]="hello, world!\n";
	for(; a[i]; read(0,i+++b,1));
	return 0;
}
void read(j,i,p)
{
	write(1, i--, 1);
}

很明显,write函数参数里的 i-- 并没有什么用。现在唯一不太正常的地方就是那个 i+++b 了。先看优先级,++ 高于 +,所以等价于 i++ + b,而b是数组名,我们学过b 和 &b[0] 是一样的,那么 i++ + b 不就相当于 b+i; i++ 了嘛。b+i 就是 &b[i]。

for循环至此已经大致清晰了,我们把for换成while,让代码更清晰一点吧。

#include <stdio.h>
int i;
int main()
{
	char a[]="]<i;++i){--i;}";
	char b[]="hello, world!\n";
	while(a[i])
	{
		read(0, &b[i], 1);
		i++;
	}
}
void read(int j, int i, int p)
{
	write(1, i, 1);
}

看得出来,main函数是遍历一遍a数组,然后传了b数组每一个元素的地址给write函数。我们看一下a和b数组,我们可以看出来a和b两个数组的长度是相同的。Amazing! 这下遍历a数组不就相当于遍历b数组嘛,看来a数组完全没用。

最后一个问题就是write函数了,这个函数是干什么的呢?我们来百度一下。

write()

用于将数据写入到文件描述符对应的文件,原型:

ssize_t write(int fd,const void*buf,size_t count);

参数说明:

fd:是文件描述符(输出到command line,就是1)

buf:通常是一个字符串,需要写入的字符串

count:是每次写入的字节数

返回值:

成功:返回写入的字节数

失败:返回-1并设置errno

ps: 写常规文件时,write的返回值通常等于请求写的字节

数count, 而向终端设备或者网络写时则不一定

现在清晰了,本程序中的write函数就是每次在屏幕中输出一个字符,而这个字符还是我们给的b数组中的内容,套个循环,这不就相当于输出b数组了嘛。最后,我再给一个最易读的代码吧

#include <stdio.h>
int main()
{
	printf("hello, world!\n");
	return 0;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值