IOCCC大赛代码分析笔记

IOCCC大赛代码分析笔记

源代码如下:

main(_){_^448&&main(-~_);putchar(--_%64?32|-~7[__TIME__-_/8%8][">'txiZ^(~z?"-48]>>";;;====~$::199"[_*2&8|_/64]/(_&2?1:8)%8&1:10);}

结果是用!号显示当前的时间。
在这里插入图片描述
为了理解代码,首先整理下:

  1. 规范主函数,加入头文件,并用i代替参数_
#include <stdio.h>
int main(int i)
{
	i^448&&main(-~i);
	putchar(--i%64?32|-~7[__TIME__-i/8%8][">'txiZ^(~z?"-48]>>";;;====~$::199"[i*2&8|i/64]/(i&2?1:8)%8&1:10);
	return 0;
}
  1. 其中~ 按位取反,对于有符号int,~i+1+i=0,因此-~i=i+1。并且&&运算符是短路求值,当左值为真的时候,才会对右值求值,进入递归。改写之后,写成
#include <stdio.h>
int main(int i)
{
	if(i^448)
		main(i+1);
	putchar(--i%64?32|-~7[__TIME__-i/8%8][">'txiZ^(~z?"-48]>>";;;====~$::199"[i*2&8|i/64]/(i&2?1:8)%8&1:10);
	return 0;
}

  1. i^448等价于i!=448中间是一个一个? :运算符,展开之后得到
#include <stdio.h>
int main(int i)
{
	if(i!=448)
		main(i+1);
	i=i-1;
	if(i%64)
		putchar(32|-~7[__TIME__-i/8%8][">'txiZ^(~z?"-48]>>";;;====~$::199"[i*2&8|i/64]/(i&2?1:8)%8&1);
	else
		putchar(10);
	return 0;
}
  1. main的默认命令行输入参数是0个,将递归改写成循环,因为从0开始进入递归,当448的时候才putchar后return,所以循环从448开始,又由于有--i,所以,从447开始递减到0。
#include <stdio.h>
int main(int i)
{
	for(i=447;i>=0;--i)
	{
		if(i%64)
			putchar(32|-~7[__TIME__-i/8%8][">'txiZ^(~z?"-48]>>";;;====~$::199"[i*2&8|i/64]/(i&2?1:8)%8&1);
		else
			putchar(10);
	}
	return 0;
}

  1. 10的ascii码是\n换行。__TIME__是一个8位的字符数组,">'txiZ^(~z?"是一个11位的字符数组,";;;====~$::199"是一个14位的字符数组,将三个变量拎出来得到
#include <stdio.h>
int main(int i)
{
	char a[9]=__TIME__;
	char b[12]=">'txiZ^(~z?";
	char c[15]=";;;====~$::199";
	int temp;
	for(i=447;i>=0;--i)
	{
		temp=-~7[a-i/8%8][b-48]>>c[i*2&8|i/64]/(i&2?1:8)%8;
		if(i%64)
			putchar(32|temp&1);
		else
			putchar('\n');
	}
	return 0;
}

  1. []的优先级最高,同时注意到7[a]=a[7],右移运算符>>优先级在-~之下,但是在位与&和位或|之前。temp对8取余,因此temp在0到7之间。位与&在位或|之前。32|temp&1的结果如下表所示
tempASCII
033 !
133 !
235 #
335 #
437 %
537 %
639 ’
739 ’

2019年7月16日17:15:01未完待续


2019年7月16日18:33:23更新
其中7[a-i/8%8][b-48]=b[ a[7-i/8%8]-48 ],a[7-i/8%8]取的是char型,48的ascii码是0,一个char型-48等于转换为int型。其中i/8%8每64个数一次轮回,打印一个\n,显示时间结果也是7*64的矩阵。__TIME__时间显示格式表示为H1H2:M1M2:S1S2。因此

ii/8%8a[7-i/8%8]
0~70S2
8~151S1
16~232:
24~313M2
32~394M1
40~475:
48~556H2
56~637H1

:的ASCII码是58,所以对应的b表如下

a[7-i/8%8]-48b[ a[7-i/8%8]-48 ]ASCII-~7[a-i/8%8][b-48]
0>6263
19697
2t116117
3x120120
4i105106
5Z9091
6^9495
7(4041
8~126127
9z122123
:?6364

看看右移后面的项c[i*2&8|i/64]/(i&2?1:8)%8

ii&2(i&2?1:8)i*2&8i*2&8|i/64c[i*2&8|i/64]c[i*2&8|i/64]/(i&2?1:8)%8
0false800; 597
1fasle800; 597
2true100; 597
3true100; 597
4false888$ 364
5fasle888$ 364
6true188$ 364
7true188$ 364

i从0~447分为7层,每层都会有变化

i 的层数c[i*2&8|i/64]c[i*2&8|i/64]/(i&2?1:8)%8
0; 59 和 $ 3677334444
1; 59 和 : 5877337722
2; 59 和 : 5877337722
3=61和 ‘1’ 4977556611
4=61和 ‘9’ 5777557711
5=61和 ‘9’ 5777557711
6=61和 ‘\0’ 077550000

2019年7月16日20:22:34 未完待续

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值