当前位置: 首页 > news >正文

这C语言代码,会让你发疯

这是一个很简单的代码,可能刚学c语言没几天的人都知道用一个for循环就可以搞定。

#include "stdio.h"
void fun(int n) {
 if(n<100) {
  printf("%d ",n); 
  fun(n+1);
 } 
 printf("%d ",n);
}

int main(void) {
 fun(1);
 return 0;
}

但是有一个朋友看了我的文章,发了这样一段代码过来

__[]={1,10,100,1000};main(_){_^400&&(_<4?1:putchar(((!((_/4)/((_%4)["3210"][__-48])%10)&&(_%4)^3)?32:((_/4)/((_%4)["3210"][__-48])%10+48))) )&&main(-~_);putchar(((!(((_+3)/4)/(((3+_)%4)["0123"][__-48])%10)&&((3+_)%4)^0)?_^398?32:48:(((3+_)/4)/(((3+_)%4)["0123"][__-48])%10+48)))&&_^1?1:putchar(10);}
 

这位朋友的叫做,「我们国庆的时候,还针对这几个题目聊了两天,技术原来真的可以拉近大家的距离。」

如果没解析,是很难理解这样非人类的代码的,里面运用到的几个技巧如下

main 函数是可以递归的,这也是很多大神写代码用到的一个技巧。

main 函数是可以没有返回值的,当然,编译的时候会出现警告,但是这并不影响运行结果。

argc != 8 等价于 argc^8

argc +1 等价于 -~argc

&& 和 || 等存在短路操作

数组 a[i] 等价于 i[a]

56,可以通过取整取余通过putchar把他们打印出来

所以上面的代码就可以拆解成

__[]={1,10,100,1000};
main(_)
{
  if (_!=20)
  {
    if (_>=4)
    {
      putchar(((!((_/4)/((_%4)["3210"][__-48])%10)&&(_%4)^3)?32:((_/4)/((_%4)["3210"][__-48])%10+48)));
    }
    main(-~_);
  }
  putchar(((!(((_+3)/4)/(((3+_)%4)["0123"][__-48])%10)&&((3+_)%4)^0)?_^398?32:48:(((3+_)/4)/(((3+_)%4)["0123"][__-48])%10+48)))&&_^1?1:putchar(10);
}

400 是用来控制输出的数量的,我们现在是输出 1~100~1

看下ascii码表,32对应的是空格,48 对应的是字符 ’0‘

然后,我们可以得出这样的解释代码

重要的部分都写在注释里面了,大家可以认真看看

__[]={1,10,100,1000};
main(_)
{
  if (_!=100)
  {
    if (_>=4)
    {
      char c = 32; // 默认打印输出一个空格‘ ’
      int number = _/4; // 这个是实际输出的数字,如果_ 等于[1,2,3,4],不会进入这个循环,如果_ 等于[4,5,6,7],number就等于1,取整数部分。
      int bit = (_%4)["3210"][__-48]; //这个就是数组取巧的地方,bit 等于 1,10,100,1000,其中的一个数字,记住 48对应的ascii是字符‘0’
                                      //先推导 (_%4)["3210"] 这部分得出结果,之后再推导 (_%4)["3210"][__-48]
                                      //(x)[y] 等价于 *(y+x)
      int bitnumber = number/bit%10;  //bitnumber 可以认为是有效数字的推导,如果是 [4,5,6,7],打印出来对应的应该是[‘空格’,‘空格’,‘空格’,‘1’]
                                      //所以这里的判断主要是为了让下面的if不要成立就可以了。
                                      //sample input:4    5   6  7
                                      //    number  :1    1   1  1
                                      //    bit     :1000 100 10 1
                                      //  bitnumber :0    0    0 1
                                      //当然,如果输入的数字很大呢?
                                      //sample input:44   45  46 47
                                      //    number  :11   11  11 11
                                      //    bit     :1000 100 10 1
                                      //  bitnumber :0    0    1 1
                                      //sample input:40   41  42 43
                                      //    number  :10   10  10 10
                                      //    bit     :1000 100 10 1
                                      //  bitnumber :0    0    1 0
                                      //上面的推导就是完成了下面的if语句,bitnumber != 0 是为了输出超过10位数的数。
                                      //_%4 == 3, 是为了输出整除4个数字的最后一位。
      if ((_%4 == 3) || bitnumber != 0)
        c = bitnumber + 48;
      putchar(c);
    }
    main(-~_);
  }
  putchar(((!(((_+3)/4)/(((3+_)%4)["0123"][__-48])%10)&&((3+_)%4)^0)?_^398?32:48:(((3+_)/4)/(((3+_)%4)["0123"][__-48])%10+48)))&&_^1?1:putchar(10);
}

至于下面的一行解释和上面的如出一撤,比较关键的地方是,这里用到了递归

调用,所以对栈的大小是有要求的。

可以试试

作者给出的详细解释如下

两份解析一起来看的话,希望大家对代码的理解有所帮助,当然了,写这样的

代码出来也是非常有意思。


今天的分享就到这里了,大家要好好学C语言/C++哟~
对于准备学习C/C++编程的小伙伴,如果你想更好的提升你的编程核心能力(内功)不妨从现在开始!

C语言C++编程学习交流圈子【点击进入】
整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)

欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!

 

相关文章:

  • 一个企业是如何做网站建设的/有产品怎么找销售渠道
  • 门户网站 管理系统/网上软文发稿平台
  • 用织梦做的网站怎么上传虚拟/汕头seo推广优化
  • wordpress添加侧栏/app营销策略
  • 对单位网站建设的意见/最近发生的新闻事件
  • 包装产品做网站/新东方教育培训机构官网
  • IT部门全被裁?不懂业务,花了几百万开发的报表系统,根本没人看
  • JAVAEE中的线程安全的集合类(包括HashtableConcurrentHashMap)
  • Intel汇编-传送大量字符串
  • 服务发现、注册-搭建Nacos服务
  • python(5) softmax回归实例
  • python3-算法刷题-链表-更新中
  • C++知识点汇总
  • 【完全背包】完全背包模板套用
  • 蚌埠住了!一份硬核的阿里P8高并发实战笔记,吊打面试官不在话下
  • c++学习25qt(一)qt下载使用和简单的信号与槽介绍
  • joomla 反序列化漏洞利用
  • 商业银行系统体系