河南梦之网网络科技有限公司
梦之网科技出品
扫描关注梦之网科技微信公众账号

扫小程序码联系客服

编写零漏洞代码所需的编码准则-梦之网科技

梦之网科技2019-10-08文章动态

盖房子时,如果负责基础工作的泥瓦匠手艺不精又没有竭尽全力,房屋质量就不可能过关。即使后期有技艺精湛的装潢布局使得建筑物的外观精美绝伦,根基没有打好也会成为“豆腐渣工程”。同理,决定软件系统质量的就是编码工作,这就要求负责编码的程序员具有过硬的基本功。

本文将和大家分析编写零漏洞代码所需的编码准则。

1

数组下标应从 0 开始

C 语言中的数组声明语句如下所示。

代码 P280 第一行

用该语句声明的数组具有如下形式。

代码 P280 第二段

此处需要注意,数组的第一个元素的下标为 0。也就是说,数组的第一个元素并不是 1 号元素,1 号元素实际上是数组的第二个元素。

程序员经常混淆这一点。这就导致为第五个元素赋值时,编写的语句形式如下所示。

代码 P280 第三行

这会导致原本应该赋给目标元素的值误赋予非目标元素,进而产生严重问题。实际上,为第五个元素赋值的正确语句如下所示。

代码 P281 第一行

指定数组下标时出现错误的原因主要在于,程序员基本功不够扎实。要想避免这些问题,就必须训练自己在指定数组下标时能够区分第一、第二、第三这种表示顺序的序数,以及一、二、三这种表示个数的基数。可以重读自己编写的代码,检查数组下标是否正确。

指定数组下标时出现的失误可能打乱整个数据集合。即应该赋给 1 号元素的值被赋给了 0 号元素,而 1 号元素仍保留原值。这与程序员的本意相背离,也很难定位引起这种数据混乱的根源所在。

这种从 1 开始对数组进行计数引起的错误又称大小差一(off-by-one)错误,顾名思义,就是少一个的意思。从 1 开始计数可能产生其他错误,比如无法处理数组的最后一个元素或引用无关数组,换言之,引用的数组可能始终是目标数组的下一个数组。

特别是在 while、for、do … while 循环语句中,这种大小差一错误更容易出现。

……中略……

计算数组所有元素总和

……中略……

根据注释可知,该 while 语句要实现的功能是计算数组元素总和,那么应该从 0 号元素开始计算。但 counter 的值是从 1 开始的,也就是说,是从 1 号元素开始计算的。这就是典型的大小差一错误。应该将该语句改写如下,counter 从 0 开始计数。

代码 P282 第二行

随着程序员编程经验日渐丰富,这种大小差一错误的出现率会逐渐降低。但编程菜鸟还是会经常出错,所以应当时刻保持警惕。特别是编写循环语句时,更要多加留意。

2

置换字符串时必须使用括号

首先分析经常被用作示例的宏函数。

代码 P282 第三行

从代码中可以看出,宏函数 SQRT(x) 可以计算 x 的平方值。从表面看这段代码并没有任何问题,运行如下语句后,可以得出 y 值为 100。

代码 P282 第四行

这是因为,该语句被置换为如下形式。

代码 P283 第一行

如果在宏函数中传递表达式作为参数,会出现什么结果呢?将下列表达式传递到宏函数,代码还能正常运行吗?

代码 P283 第二行

上述语句被置换为如下形式。

代码 P283 第三行

根据该表达式的运算符优先级,可以推测运算顺序如下,计算结果为 230。

代码 P283 第四行

我们预期的结果应该是 900,实际结果竟然是 230。

如何才能避免这种问题呢?如下所示,在定义宏函数时使用括号。

代码 P283 第五行

如上定义宏函数后,再用下列语句调用该函数。

代码 P283 第六行

可以得出正确答案 900,因为该语句被置换为如下形式。

代码 P283 第七行

3

文件必须有开就有关

我编写过一个处理主文件的程序,该主文件一次需要保管大约 3 万份数据。而且主文件的特性要求,允许多个程序拥有同时使用该文件的权限。

项目快要收尾时,我开始进行综合测试。此时,问题出现了。所有程序中,只有我编写的这个程序出现了问题。我从头开始检查程序代码,却没有发现任何异常。虽然在各种编译器配置下不断编译、执行,但界面始终显示“无法打开文件”的错误信息。

这实在令人百思不得其解。我耗费了整整一周的时间死抠代码。当然,整个项目也因此延期一周。1500 行代码让我眼花、恶心,最后身心交瘁,几乎要放弃。就在这时,我突然灵光乍现:“说不定,并不是程序有问题。”

如果不是程序有问题,那么是什么问题呢?我开始查看所有可能与该主文件有关的程序。除了我自己编写的程序外,还检查了其他所有人编写的程序。就这样,一周又过去了。

文章关键词
程序员
代码
编码
编译器