browser icon
You are using an insecure version of your web browser. Please update your browser!
Using an outdated browser makes your computer unsafe. For a safer, faster, more enjoyable user experience, please update your browser today or try a newer browser.

第四个“回”字

Posted by on 2003 年 01 月 02 日

你可以任意转载本文,但请在转载后的文章中注明作者和原始链接。
媒体约稿请联系 titilima_AT_163.com(把“_AT_”换成“@”)。

前些日子在腾讯的BBS上看到一篇贴子,是讲代码优化的。读着读着不爽至极。内容大抵是对以下一段代码进行优化:

if ( a == 5 )
    return 1;
else
    return 0;

我的答案是:

return ( 5 == a );

然后据评分标准,我应得85分。给90分的是利用A编译器来进行预处理优化,如下:

#ifdef CompilerA // 你已经知道A编译器作为一种特例,将T返回0、F返回-1
    return ( 5 == a ) + 1;
#else
    return ( 5 == a );
#endif

当然还有给99分的,如下:

return ( 5 == a ) ^ ( 1 == 1 );

下面讨论的人感慨很多,几乎无一不表示对作者的钦佩。

我开始感到了一种东西:科举的阴魂。

记得我上中学的时候,学过鲁迅先生的《孔乙己》一文,其中有一段非常经典:孔乙己问酒店小伙计会不会写“回”字,然后又告诉他,“回”字有四种写法。课文下边的注释写的是:“回”字有四种写法:回、囘、囬……还有一个“回”,字库里没有,看来GB_2312也将其删掉了,我只好用星号把它画在下面了。——继续说注释,注释说一般只用前三种写法(就是我的三种),极少有用第四种写法的,但是孔乙己这种深受科举教育毒害的读书人,经常会把这些没用的东西当成学问。

**********************
*                    *
*    ************    *
*    *          *    *
*    ************    *
*    *          *    *
*    ************    *
*    *          *    *
*    ************    *
*                    *
**********************

当今中国的代码界,竟还有很多把会写第四个回字当成本领的人!

再举一个例子,这个例子是我想出来的。

a <<= 3;

我来解释一下,对于C/C++的初学者而言,他们想表达这个意思,通常会这样写:

a *= 8;

然后我告诉他们,我用的是位运算,效率比他们高。……我已经能听见有人在骂我了。

对于这种现象,我不想多说。唯一要提醒诸位的是现在的时代是讲究团队开发的时代,这样的代码势必只会为团队开发造成麻烦,而不会有人夸奖你的学问。

教我C语言的老师说过,在印度,给出一个题目,不同的程序员能够写出几乎一样的代码。而把一个题目给不同的中国程序员,答案将是五花八门的。

印度的软件工业水平超过中国,大家有目共睹。

中国的代码界需要被拯救。

还好,现在很多人注意到了这个问题,也有一部分关于编码规范的书出版了,我亦曾拜读过几本,其中似乎都在强调这个问题:不要写令人费解的代码。

程序设计语言结构化之前,有很多算法高手操着一把宝剑——goto,goto来goto去,能goto出一段天书般的高效代码。然而结构化的程序设计语言根本没有因为这些代码的高效而被扼杀在摇篮里,相反,goto却被关进了监狱。我不多说了,相信大家都明白我的意思。

如果说不会写第四个回字会被当作文盲,我倒宁愿当文盲。

我觉得return (5 == a);挺好。

补记

后来这篇文章贴到了CSDN上面,结果招来一阵臭骂,亦引起一系列讨论。现在看起来,这篇文章未免偏激与幼稚。所谓偏激,就是如网友所说,自己看不懂的代码就说是奇技淫巧;所谓幼稚,就是我其中举出的例子难免幼稚。比如以下程序:

#include <iostream>
using namespace std;

void main()
{
    int a = 1, b = 1;
    a << = 3;
    b *= 8;
}

在VC 6.0编译器的优化下,会生成相同的汇编代码(左移3位实现乘以8):

; a <<= 3;
00401056 mov eax,dword ptr [ebp-4]
00401059 shl eax,3
0040105C mov dword ptr [ebp-4],eax
; b *= 8;
0040105F mov ecx,dword ptr [ebp-8]
00401062 shl ecx,3
00401065 mov dword ptr [ebp-8],ecx

由是看来,我的示例难免不能站住脚了。

但是,编写清楚易懂的代码的确是一件很重要的事情,说到底天书一般的代码都是不可取的。

李马 2003/6/26 于山西太原

订阅本站

5 Comments

  • At 2007.08.17 14:39, hurryhx said:

    ; a <<= 3; 00401056 mov eax,dword ptr [ebp-4] 00401059 shl eax,3 0040105C mov dword ptr [ebp-4],eax ; b *= 8; 0040105F mov ecx,dword ptr [ebp-8] 00401062 shl ecx,3 00401065 mov dword ptr [ebp-8],ecx

    • At 2008.03.28 00:38, LL said:

      呵呵,有点意思……
      第一次见学理的人还知道“回”字有四种写法。。
      o(^O^)o

      • At 2008.04.30 16:48, zkkpkk said:

        哈哈最后的汇编语句是一样的,我想啊编译器也没那么傻,难道左移就是shl,乘就用loop?所以a<<=3还是被当头一棒了。

        • At 2008.05.02 03:34, 请教 said:

          请问 ( 5 == a ) ^ ( 1 == 1 ) 有啥含义?

          • At 2008.05.02 11:24, 李马 said:

            To 请教:
            看看汇编代码吧。不过,既然你看起来很费劲,就说明编写清楚易懂的代码的确是一件很重要的事情。

            (Required)
            (Required, will not be published)