当前位置: 首页 > 科技观察

90%的程序员都犯过代码错误

时间:2023-03-12 04:42:52 科技观察

最近参加了很多次codereview会议,在review过程中,几乎每次都发现一些问题出现。挑几个比较典型的问题来解释。这些问题都是初级问题,解决起来也很容易。只要掌握方法,有意识地避免,就可以在短时间内快速提高代码质量。所谓投资小,见效快。变量命名不明确和多义命名变量时最重要的考虑因素是名称完整准确地描述变量所代表的交易。易于阅读,不要与其他交易混淆。例如:if(staff_id==0){printf("系统备案,不是员工备案");}上面代码中,staff_id为员工编号,staff_id为0表示系统备案。这个词是多义的,本来应该把系统和人分开的,但是一个变量被混淆了。如果调用者有bug,忘记给初始化的变量赋值,就会走向意想不到的逻辑。解决方法是变量名首先要符合变量的实际含义,不能有歧义;对于变量名,没有具体的值来表示特殊的逻辑。有些代码会对变量无法获取的值赋予其他含义。感觉是省事,实则后患无穷。例如,如果用户名不能为空,则使用空值表示用户数据已被删除。而且判断数据是否删除的代码也是莫名其妙。总之,变量命名一定要保证没有“潜规则”,防止给自己挖坑。幻数命名的使用尚不清楚。更严重的是没有命名,直接使用幻数。如果连评论都没有,那就只能靠猜测了。使用magicnumber有两个缺点:1.修改不方便。用常量代替幻数是“参数化”程序的一种方式。只需要修改一个地方,而不需要在代码中到处修改。比如代码中默认绑定的端口是80,如果不换成常量,软件升级时默认端口会变成443。要在整个代码中搜索数字80,既费时又容易改正。2.代码不易阅读。只有一个数字,具体含义很难理解。for(inti=0;i<13;++i){...}上面的代码,只看13,谁能猜到是什么意思,为什么要用13这个值呢?也许只有写代码的人和天知道。如果写代码的人久而久之忘记了,只有天知道。也有同学会问,如果有些数只用在一个地方,命名为常量会不会太麻烦?答案是:没问题。给幻数起个好名字是对的,也是应该做的事。不要因为麻烦而停止这样做。有时为了取一个准确的名字,你甚至得查字典。有一个常见的判断方法:1.如果引用magicnumber的地方不超过3个,直接用这个数字效果不大。如果超过3个,都代表相同的数值意义,或者乖乖换成有意义的变量名。2.如果magicnumber本身代表的是纯数字定义,比如几米或者几千克,就把它作为参数传过去。函数的定义清楚地表达了形参所代表的意义。看到用到的地方和函数定义,就知道数字代表多少个单位了,可以用幻数。但是如果用数字表示类型,比如constintieBrowser=1;constintchromeBrowser=2;表示浏览器的类型,如果直接看到1或2,是看不懂什么意思的。即使在函数声明中已经提到了浏览器类型,也不要使用幻数。幻数的解决方法很简单:用枚举、常量等代替幻数。ifelse、switch等逻辑判断语句过长。例如,下面的伪代码有很多条件分支。只有长的ifelse语句或switch语句才能表达完整的逻辑。想想能不能通过“表驱动”来优化。constantCN=1;constintUS=2;constintUK=3;stringlanguage;if(country==CN){language="Chinese";}elseif(country==US){language="english";}elseif(country==UK){language="english";}else{language="";}条件分支太多有几个不好的地方:1.代码太长,难以阅读。如果超过一屏所能表达的长度,就不得不翻页阅读代码,会大大降低阅读代码的效率。因为代码的信息密度太低了。2.不易扩展和修改代码。就像上面的例子,如果增加了一个新的条件判断,那么就需要增加一个新的ifelse语句。既然修改了逻辑,就要重新测试,防止出错。太长的逻辑分支可以用“表驱动”的方法代替。将每个条件要使用的数据放到一个“表”中。使用条件分支的判断条件对表中的数据进行索引。上面代码可以修改为constantCN=1;constintUS=2;constintUK=3;stringlanguageTable[]={"","Chinese","English","English"};//首先判断country变量是否在定义的CN、US和UK,如果你继续language=languageTable[country];修改后,代码变得很短,一眼就能看出代码表达的逻辑。而且以后只更新数据,逻辑部分不需要修改。使用“表驱动”后,逻辑和数据分离。使新数据的修改简单明了,一目了然。总结以上只是对几种常见的代码编写错误的简单描述。只要稍加注意,就可以在短时间内快速提升代码质量。具体方法可以参考一些代码规范,或者重构方面的书籍,比如《TableDrive》,里面会有比较详细的介绍。最本质的是意识上要有足够的认识。代码是写给人们阅读的。写代码的时候一定要有同理心,想着以后看代码的人能读得尽量不费力。换个角度想,如果你是reviewer,或者是后来接手代码的人,你会喜欢这段代码吗?毕竟,阅读的代码远远多于编写的代码。确保您的代码易于阅读,而不仅仅是易于编写。