对于程序员来说什么叫简练

这篇文章通篇都是教你如何把你写的像垃圾一样的C源码变得像屎一样。

当你看源码之前你必须要知道我写这篇文章只是拿很简单的东西在举例子:虽然降低了可读性,但是可以通过加注释行的方式来提高可读性。毕竟绝大多数程序属于用已经有的东西搭积木,所以我们更应该追求的是速度。即使改得面目全非。可读性就交给说明文档和注释行吧

首先必须声明的是,正常人干不出来这样的事儿。最近译文如何做一个编译器好像很红的样子,那么我们来讲一下如何把你写的已经很糟糕的C的源码变得更糟糕。使编译变得更简单,但是要建立在降低可读性的前提条件下。
如果你好奇我为什么要这样做,那么去看那个非常火的译文《如何做一个编译器》,这一部分可以作为我们在编译之前的一项简化的工作。
对,没错!能干出来这种事儿的除了我真是没谁了。编写一个程序的目的是把你其他写的本来就不好的源文件变得更糟。(雾) 实际上,说真的我追求的永远是代码的写的短小,说实话我喜欢短小的东西,比如我爱人的某一部分(污)
在学习如何提高运行速度之前我们先看一下我们示例程序的提速成果:


提速前
提速后


比如正常人求1到100的和的代码:

#include main()
{ int i=0,sum=0; for(i=1;i<=100;i++)
    {
        sum=sum+i;
    } printf("sum=%d\n",sum);
}

但是像我这种贱婊子就会改一改:

#include main()
{ int i,sum=0; for(i=1;i<=100;i++)
        sum+=i; printf("sum=%d\n",sum);
}

似乎没变多少,然后我就会突然想起一个叫高斯的哥们儿。

#include main()
{ int sum=0;
    sum=(1+100)*100/2; printf("sum=%d\n",sum);
}

已经被我改到像垃圾一样了,但是,我这样的贱婊子会把它弄的像屎一样的。

#include main()
{ int sum=5050; printf("sum=%d\n",sum);
}

然后,还不甘心:

#include main()
{ printf("sum=5050\n");
}

终于可以消停了。你可以看出来代码被我改的面目全非,但是其返回结果永远可是说是“正确”的。
所有的代码是不是都可以这样呢?
经过长期的实践,我得出了其中一部分是可以的,另一部分是不可以的。那么这种机械的任务,我们就可以让计算机帮我们干,特别是我现在在电子图书馆使用的这台像我写的源码一样屎的32位台式机。运行速度简直弱爆了。
那么,我们就开始吧!首先在前几部分我要告诉你们一些非常简单的可以改的源码,接下来的部分会将如果想计算机帮我们做这件恶心事儿。(作为一个资深粪叉儿,我非常喜欢干这个事情)
首先就是只输出的程序,通常可以直接变成结果的输出,就比如求1到100的和这种程序。
这种呢就是要分析最后的结果啦,直接变成hello world那种程序就好了。(把代码写得尽可能短,目前是某些变态的公司的面试题,我曾经还在外面工作的时代遇到过)
然后就是一类较为简单的输入输出的程序,虽然不能变得极为简单,但是也可以尽量的化简。
一般正常的程序员是这样写的:

#include main()
{ int i=0,j=0,sum=0; scanf("%d%d",&i,&j); while(i<=j)
    {
        sum=sum+i;
        i++;
    } printf("sum=%d\n",sum);
}

聪明一些的程序员是这样写的:

#include main()
{ int i,j,sum=0; scanf("%d%d",&i,&j); while(i<=j)
    {
        sum+=i;
        i++;
    } printf("sum=%d\n",sum);
}

如果你也认识高斯那哥们儿,你可能会这样写

#include main()
{ int i,j,sum=0; scanf("%d%d",&i,&j);
    sum=(i+j)*(j-i+1)/2; printf("sum=%d\n",sum);
}

如果你上过看门儿大爷教的数学课(实际上,我之前做过长期的数学教员,所以看我的所有的文章可能需要你先去找看门儿大爷来补习一下数学)
那么你肯定能推导出来这样的式子


式子


你要知道,更少的括号是给编译的时候省力的秘诀,当然我也给了一种看门儿大爷没告诉你的求和公式,当然这种公式的使用前提是公差是1。
这时候你会告诉我,你的源码变成了:

#include main()
{ int i,j,sum=0; scanf("%d%d",&i,&j);
    sum=(j*j-i*i+j+i)/2; printf("sum=%d\n",sum);
}

当然,我会把它写得更短小:

#include main()
{ int i,j; scanf("%d%d",&i,&j); printf("sum=%d\n",(j*j-i*i+j+i)/2);
}

为什么不把sum的值写成更简单的多项式的形式呢?换句话说,你使用的括号还可以更少:

#include main()
{ int i,j; scanf("%d%d",&i,&j); printf("sum=%d\n",j*j/2-i*i/2+j/2+i/2);
}

你会发现这里面实际上还有可以简化的部分,可以吧除以2变成向右移一位
但是,我们知道位运算的优先级要低于加减法,所以,源码会变成这样:

#include main()
{ int i,j; scanf("%d%d",&i,&j); printf("sum=%d\n",j*j-i*i+j+i>>1);
}

附录:
演示程序提速前源码:

#include main()
{ int i=0,j=100,sum=0; while(i<=j) 
  {
    sum=sum+i;
    i++;
  } printf("sum=%d\n",sum);
}

演示程序提速后源码:

#include main()
{ int i=0,j=100; printf("sum=%d\n",j*j-i*i+j+i>>1);
}

你一定会问,这样程序的可读性降低了很多,我觉得这些你可以通过注释行来弥补。当然,我写文章的目的是做一个简化的程序出来,那么你只需要掌握简化的基本思路,就可以了。永远记住,循环和括号是我们讨厌的东西,除了不得已的时候,我们不会使用的。

回到

顶部