6个变态的C语言Hello World程序——更好的理解C(4、5、6)

hello4.c

  1. main(){int i,n[]={(((1<<1)<<(1<<1)<<(1<<  
  2.     1)<<(1<<(1>>1)))+((1<<1)<<(1<<1))), (((1  
  3.     <<1)<<(1<<1)<<(1<<1)<<(1<<1))-((1<<1)<<(  
  4.     1<<1)<<(1<<1))+((1<<1)<<(1<<(1>>1)))+ (1  
  5.     <<(1>>1))),(((1<<1)<<(1<<1)<<(1<<1)<< (1  
  6.     <<1))-((1<<1)<<(1<<1)<<(1<<(1>>1)))- ((1  
  7.     <<1)<<(1<<(1>>1)))),(((1<<1)<<(1<<1)<<(1  
  8.     <<1)<<(1<<1))-((1<<1)<<(1<<1)<<(1<<(1>>1  
  9.     )))-((1<<1)<<(1<<(1>>1)))),(((1<<1)<< (1  
  10.     <<1)<<(1<<1)<<(1<<1))-((1<<1)<<(1<<1)<<(  
  11.     1<<(1>>1)))-(1<<(1>>1))),(((1<<1)<<(1<<1  
  12.     )<<(1<<1))+((1<<1)<<(1<<1)<<(1<<(1>>1)))  
  13.     -((1<<1)<<(1<<(1>>1)))),((1<<1)<< (1<<1)  
  14.     <<(1<<1)),(((1<<1)<<(1<<1)<<(1<<1)<<(1<<  
  15.     1))-((1<<1)<<(1<<1))-(1<<(1>>1))),(((1<<  
  16.     1)<<(1<<1)<<(1<<1)<<(1<<1))-((1<<1)<< (1  
  17.     <<1)<<(1<<(1>>1)))-(1<<(1>>1))), (((1<<1  
  18.     )<<(1<<1)<<(1<<1)<<(1<<1))- ((1<<1)<< (1  
  19.     <<1)<<(1<<(1>>1)))+(1<<1)), (((1<<1)<< (  
  20.     1<<1)<<(1<<1)<< (1<<1))-((1<<1)<< (1<<1)  
  21.     <<(1<<(1>>1)))-((1<<1) <<(1<< (1>>1)))),  
  22.     (((1<<1)<< (1<<1)<<(1<<1)<< (1<<1))- ((1  
  23.     <<1)<<(1<<1)<<(1<<1))+((1<<1)<< (1<<(1>>  
  24.     1)))), (((1<<1)<<(1<<1) <<(1<<1))+(1<<(1  
  25.     >>1))),(((1<<1)<<(1<<1))+((1<<1)<< (1<<(  
  26.     1>>1))) + (1<< (1>>1)))}; for(i=(1>>1);i  
  27.     <(((1<<1) <<(1<<1))+((1 <<1)<< (1<<(1>>1  
  28.     ))) + (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

  1. #include<stdio.h>  
  2.     #define __(a) goto a;  
  3.     #define ___(a) putchar(a);  
  4.     #define _(a,b) ___(a) __(b);  
  5.     main()  
  6.     { _:__(t)a:_('r',g)b:_('$',p)  
  7.       c:_('l',f)d:_(' ',s)e:_('a',s)  
  8.       f:_('o',q)g:_('l',h)h:_('d',n)  
  9.       i:_('e',w)j:_('e',x)k:_('\n',z)  
  10.       l:_('H',l)m:_('X',i)n:_('!',k)  
  11.       o:_('z',q)p:_('q',b)q:_(',',d)  
  12.       r:_('i',l)s:_('w',v)t:_('H',j)  
  13.       u:_('a',a)v:_('o',a)w:_(')',k)  
  14.       x:_('l',c)y:_('\t',g)z:___(0x0)}  

这段代码看上去排列比较整齐,但语法比较奇怪。仔细看看,你会发现涉及的主要就两个内容:goto语句的使用以及宏定义的使用。

         所有冒号左边的都是语句标号。如mian函数里面的第一句翻译过来为_:goto t;执行这个语句后跳转到语句标号为t的语句,即t:('H',j),完成所有的宏替换,代码转换为:

  1. main()  
  2. {  
  3.     _:goto t;  
  4.     a:putchar('r'); goto g;  
  5.     b:putchar('$'); goto p;  
  6.     c:putchar('l'); goto f;  
  7.     d:putchar(' '); goto s;  
  8.     e:putchar('a'); goto s;  
  9.     f:putchar('o'); goto q;  
  10.     g:putchar('l'); goto h;  
  11.     h:putchar('d'); goto n;  
  12.     i:putchar('e'); goto w;  
  13.     j:putchar('e'); goto x;  
  14.     k:putchar('\n'); goto z;  
  15.     l:putchar('H'); goto l;  
  16.     m:putchar('X'); goto i;  
  17.     n:putchar('!'); goto k;  
  18.     o:putchar('z'); goto q;  
  19.     p:putchar('q'); goto b;  
  20.     q:putchar(','); goto d;  
  21.     r:putchar('i'); goto l;  
  22.     s:putchar('w'); goto v;  
  23.     t:putchar('H'); goto j;  
  24.     u:putchar('a'); goto a;  
  25.     v:putchar('o'); goto a;   
  26.     w:putchar(')'); goto k;  
  27.     x:putchar('l'); goto c;  
  28.     y:putchar('\t'); goto g;  
  29.     z:putchar(0x0);  
  30. }   
语句间的跳转顺序为:

_ >>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语言的乐趣之所在。写出这样的混乱代码,确实是件很酷的事情!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值