zpl代码可以编译的特殊字符_国际C语言混乱代码大赛(IOCCC)代码解析

2019年Best one-liner:http://ioccc.org/2019/burton/hint.html

这个程序只有一行:

e,n,j,o,y;main(){for(++o;n=-~getchar();e+=11==n,y++)o=n>0xe^012>n&&'`'^n^65?!n:!o?++j:o;printf("%8d%8d%8dn",e^n,j+=!o&&y,y);}

功能就是统计一个文件里的行数、单词数、字母数。

加上换行格式化后是这样的:

e, n, j, o, y;
main()
{
    for (++o; n = -~getchar(); e += 11 == n, y++)
        o = n > 0xe ^ 012 > n && '`' ^ n ^ 65 ? !n : !o ? ++j : o;
    printf("%8d%8d%8dn", e ^ n, j += !o && y, y);
}

编译指令:

WARN="-Wno-implicit-int -Wno-missing-variable-declarations -Wno-parentheses"
clang -Wall -Wextra -Weverything -pedantic $WARN -include stdio.h -o prog prog.c

这块儿我也不熟,但看字面意思应该就是说把默认的变量设为int,然后加上stdio.h

然后就是代码说明了:

先看循环条件:

n=-~getchar()//getchar函数不断读取字符,到结尾后返回EOF(-1),而-~(-1) =0;所以就可以跳出循环
 e += 11 == n, y++//e:行数统计 遇到换行符+1  y:字符统计 直接+1

可以看到行数信息和字符数信息很容易就实现了。

然后就是for中的循环语句,嵌套了两次三元运算符,主要功能就是统计单词个数。

6c016d7ec8d8ccfaaceeb669fc51e2fe.png

逻辑是这样的:

如果当前字符为空格(或者换行,水平定位,垂直定位,换页等)等分割字符,且前一个字符不是分割字符,那么单词数加1.

o这个变量这里就是用来记录前一个是否是特殊字符的。

具体解释:

(n > 0xe) ^ (012 > n)://输入字符为ascii中的9 到13时为假 其余为真
//即水平定位、换行、垂直定位、换页、归位;在ascii表中正好是连在一起的
  '`' ^ n ^ 65//输入为空格时为假

所以 n > 0xe ^ 012 > n && '`' ^ n ^ 65合起来就是分割字符时为假,其余为真

!n//恒等于0;用来迷惑人的

连起来就是说,

  • 所以如果当前字符是正常字符,就把o标记为0;
  • 如果当前字符是分割字符,
    • 且当前的o=0(表示前一个字符不是分割字符),那么单词数加一,o的值变为非0(这里是把j的值赋给了o)
    • 否则o的值不变

最后一行就是打印了,循环退出的时候n=0;所以e^n就是e;

j += !o && y这个里面的y也是一定大于0的,只是用来混淆的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值