编码规范中的禁忌(个人向
前言
这是一篇介绍一些我认为在编码规范中不应该随便触碰的禁忌,因为我认为它们会影响我们的阅读,或者是增加逻辑上理解的困难程度,当然这或许会带着一些主观想法在里面,不过这些应该都是我在工作中发现的问题,对我造成了影响的,同时也说明顺序是无序的.
如果有不同意见或发现我的错误想法,欢迎下面评论指正.
目录
工程中是阅读第一,技巧第二,竞赛才是技巧第一,阅读什么的狗带.
–某知乎看见过的一答者想法
- 逻辑类
1, do while
12345 int iCnt = 0,id;do{id = rand()%10;++iCnt;}while(iCnt < 10 && (id == hero.id || !lock(id)));
上面的代码是在做竞技场随机敌方的时候乃至的代码,是想表达:随机10次,10次内停止条件是id不等于英雄的id,而且能够锁定它,其实讲出来后,并不难于理解,不过当别人不知道要做啥,第一次看的时候,我想还是应该会比较绕的,特别是在写了半天代码,头脑已经跟不上的时候…而且这是逻辑比较少的时候,多了会更难.
对于这种判断不只一个的,或者包含一个的吧(毕竟我是dowhile
黑)尽量用for
代替吧,比如上面的代码如果是我,我会写成:
1234567 int id;for(int i = 0; i < 10;++i){id = rand() % 10;if(id == hero.id) continue;if(!lock(id) continue;break;}
我相信这样的代码,看起来就比较容易理解了.
题外话,我其实有点是while
黑,我用while
的地方,一般只用在曾经acm的程序读入如while(~scanf())
这样的代码,和宏定义如定义一个如果为空就返回的宏:#define TS_NULL_RETRUN(ptr) do{if(!ptr)return;}while(0);
其于地方,如果能用for
的,我一般会用for
,我认为for
更便于理解甚至是阅读,有时候甚至是缩代码的良方。
2, 先除后乘和浮点数
在运算过程中如果能不使用浮点数,就尽量不要使用浮点数, 当我们用浮点总会有意外的收获.
前一段时间,英雄相关的数据,我负责服务端(语言是c#
),在血量这里就改过好多次。我们的血量计算方式要乘以各种系数(按英雄品质得到个1.2,1.5,HP成长值*0.8什么的),第一修改的时候,因为前端(语言是cpp
)用了120*0.01,导致血量比我算来少一点,单步跟下去发现是浮点的问题,因为120*0.01返回了1.199999.然后各种乘,就跪了.我提出叫前端小哥不要用乘小于1的小数,然后他改了,这时候发现没问题了。。可过了几天,又发现前端多了我一滴血,我猜这肯定又是浮点的问题,我单步跟下去发现他是把原来的120*0.01,改成了120/100.0f.这时候返回了1.200001…于是有了第二次修改,这时候我便强烈要求他改成把这除法放在后边,有乘的地方先乘起来(前提是要保证能存下)再除,避开浮点数,如果int
或者long long
不能存下再考虑其他方法.这次修改之后,再也没出过问题
- 阅读类
1, if else
->switch
这里是说ifelseif
是特指常量类,能用switch
.而且数量不只2个的时候,尽量用switch
好,比如:
|
|
这样的代码在外观上看起来感觉不太合胃口的.甚至觉得是差评的代码.说得夸张一点就是,我在阅读的时候,心里活动会比较多(相对switch
来说).如果换成switch
的代码:
|
|
这样我读到第一行我就知道下面是常量,数字或者字符串等.这时候便会通知大脑这里没有运算,只看等于几就好了.
2, #define
<–> const
这里比较个人向.现在公司的代码中,是禁止后者出现的,一切常量定义和函数定义,都是用的宏如:
这是公司代码风格,当然我也一直在用,毕竟一个团队嘛风格差别太大肯定不行。不过在我的主观认知中,应该把常量定义和函数定义分开,比如:
像这样我在阅读的时候,有种无法表达出来的感觉,反正就是比上面种要好一些.
当然,如果你有物是c#之类,没有宏这么一说,那就不用花时间考虑这种无聊的问题了,顺便PS:在C++Primer中,也是强烈推荐用const
不要用#define
,上面说了各种const
的好处比如作用域等.