hello4.c
[cpp] view plaincopyprint?
- main(){int i,n[]={(((1<<1)<<(1<<1)<<(1<<
- 1)<<(1<<(1>>1)))+((1<<1)<<(1<<1))), (((1
- <<1)<<(1<<1)<<(1<<1)<<(1<<1))-((1<<1)<<(
- 1<<1)<<(1<<1))+((1<<1)<<(1<<(1>>1)))+ (1
- <<(1>>1))),(((1<<1)<<(1<<1)<<(1<<1)<< (1
- <<1))-((1<<1)<<(1<<1)<<(1<<(1>>1)))- ((1
- <<1)<<(1<<(1>>1)))),(((1<<1)<<(1<<1)<<(1
- <<1)<<(1<<1))-((1<<1)<<(1<<1)<<(1<<(1>>1
- )))-((1<<1)<<(1<<(1>>1)))),(((1<<1)<< (1
- <<1)<<(1<<1)<<(1<<1))-((1<<1)<<(1<<1)<<(
- 1<<(1>>1)))-(1<<(1>>1))),(((1<<1)<<(1<<1
- )<<(1<<1))+((1<<1)<<(1<<1)<<(1<<(1>>1)))
- -((1<<1)<<(1<<(1>>1)))),((1<<1)<< (1<<1)
- <<(1<<1)),(((1<<1)<<(1<<1)<<(1<<1)<<(1<<
- 1))-((1<<1)<<(1<<1))-(1<<(1>>1))),(((1<<
- 1)<<(1<<1)<<(1<<1)<<(1<<1))-((1<<1)<< (1
- <<1)<<(1<<(1>>1)))-(1<<(1>>1))), (((1<<1
- )<<(1<<1)<<(1<<1)<<(1<<1))- ((1<<1)<< (1
- <<1)<<(1<<(1>>1)))+(1<<1)), (((1<<1)<< (
- 1<<1)<<(1<<1)<< (1<<1))-((1<<1)<< (1<<1)
- <<(1<<(1>>1)))-((1<<1) <<(1<< (1>>1)))),
- (((1<<1)<< (1<<1)<<(1<<1)<< (1<<1))- ((1
- <<1)<<(1<<1)<<(1<<1))+((1<<1)<< (1<<(1>>
- 1)))), (((1<<1)<<(1<<1) <<(1<<1))+(1<<(1
- >>1))),(((1<<1)<<(1<<1))+((1<<1)<< (1<<(
- 1>>1))) + (1<< (1>>1)))}; for(i=(1>>1);i
- <(((1<<1) <<(1<<1))+((1 <<1)<< (1<<(1>>1
- ))) + (1<<1)); i++) printf("%c",n[i]); }
这段代码看上去比较长比较乱,其实涉及的主要就是C语言位运算中的位移运算:
<<——左移,>>——右移。一般地,左移以为代表乘以2,左移2位代表乘以4;右移一位相当于除2,右移2位代表除4;
上面代码中,主要就是通过位移,依次为整型数组int n[]赋值,分别对应的是“Hello, world!"中各字符的ASCII码值。这个可以自行计算验证。然后用%c格式化输出,将整型转化为ASCII码中对应的字符。
C语言位运算中还涉及到位逻辑运算:
1.单目运算符:~(取反)
2.双目运算:&(按位与) 、 |(按位或)、 ^(按位异或)
hello5.c
[cpp] view plaincopyprint?
- #include<stdio.h>
- #define __(a) goto a;
- #define ___(a) putchar(a);
- #define _(a,b) ___(a) __(b);
- main()
- { _:__(t)a:_(‘r‘,g)b:_(‘$‘,p)
- c:_(‘l‘,f)d:_(‘ ‘,s)e:_(‘a‘,s)
- f:_(‘o‘,q)g:_(‘l‘,h)h:_(‘d‘,n)
- i:_(‘e‘,w)j:_(‘e‘,x)k:_(‘\n‘,z)
- l:_(‘H‘,l)m:_(‘X‘,i)n:_(‘!‘,k)
- o:_(‘z‘,q)p:_(‘q‘,b)q:_(‘,‘,d)
- r:_(‘i‘,l)s:_(‘w‘,v)t:_(‘H‘,j)
- u:_(‘a‘,a)v:_(‘o‘,a)w:_(‘)‘,k)
- x:_(‘l‘,c)y:_(‘\t‘,g)z:___(0x0)}
这段代码看上去排列比较整齐,但语法比较奇怪。仔细看看,你会发现涉及的主要就两个内容:goto语句的使用以及宏定义的使用。
所有冒号左边的都是语句标号。如mian函数里面的第一句翻译过来为_:goto t;执行这个语句后跳转到语句标号为t的语句,即t:(‘H‘,j),完成所有的宏替换,代码转换为:
[cpp] view plaincopyprint?
- main()
- {
- _:goto t;
- a:putchar(‘r‘); goto g;
- b:putchar(‘$‘); goto p;
- c:putchar(‘l‘); goto f;
- d:putchar(‘ ‘); goto s;
- e:putchar(‘a‘); goto s;
- f:putchar(‘o‘); goto q;
- g:putchar(‘l‘); goto h;
- h:putchar(‘d‘); goto n;
- i:putchar(‘e‘); goto w;
- j:putchar(‘e‘); goto x;
- k:putchar(‘\n‘); goto z;
- l:putchar(‘H‘); goto l;
- m:putchar(‘X‘); goto i;
- n:putchar(‘!‘); goto k;
- o:putchar(‘z‘); goto q;
- p:putchar(‘q‘); goto b;
- q:putchar(‘,‘); goto d;
- r:putchar(‘i‘); goto l;
- s:putchar(‘w‘); goto v;
- t:putchar(‘H‘); goto j;
- u:putchar(‘a‘); goto a;
- v:putchar(‘o‘); goto a;
- w:putchar(‘)‘); goto k;
- x:putchar(‘l‘); goto c;
- y:putchar(‘\t‘); goto g;
- z:putchar(0x0);
- }
语句间的跳转顺序为:
_ >>t>>j>>x>>c>>f>>q>>d>>s>>v>>a>>g>>h>>n>>k>>z
hello6.cpp(注意本程序只能被C++编译器编译)
#include <stdio.h> #define _(_) putchar(_); int main(void){int i = 0;_( ++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++ ++++i)_(++++++++++++++++++++ ++++++++++++++++++++++++++++ ++++++++++i)_(++++++++++++++ i)_(--++i)_(++++++i)_(------ ---------------------------- ---------------------------- ---------------------------- ---------------------------- ----------------i)_(-------- ----------------i)_(++++++++ ++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++ ++++++++++++++++++++++++++i) _(----------------i)_(++++++ i)_(------------i)_(-------- --------i)_(---------------- ---------------------------- ---------------------------- ---------------------------- ---------------------------- ------i)_(------------------ ---------------------------- i)return i;}
这段代码看上去比较炫,其实是很无聊的,通过自增,自减运算符为 i 赋值,而这些值都是"Hello, world!"字符串中对应字符的ASCII码值,用putchar(c)输出。
写到这儿,六个变态的C语言Hello world程序全部介绍完毕。咋一眼看上去确实不知所云,在我不说明的情况下你鞥一眼辨别程序要输出的是什么吗?我想还是有点困难的。当然 我们不提倡C语言混乱代码,写出一些让人摸不着头脑礼节性差的代码,但通过分析这些混乱的代码,明白其中的道理所在,通过分析,层层解开混乱代码后的神秘面纱,我想这应该也算是学习C语言的乐趣之所在。写出这样的混乱代码,确实是件很酷的事情!