C语言代码评审小结

点击查看全文


在实际的软件开发项目中,代码评审是一个必不可少的流程。代码评审,也称之为代码复查,是指通过阅读开发人员所写的代码来检查源代码与编码规范的符合性以及代码质量的活动。总的说来,代码评审的好处有以下几点: 
第一,发现程序问题,提高代码质量。 
第二,理清代码逻辑,开阔编程思路。 
第三,促进团队交流,提升开发技能。

代码评审的大体流程是这样的: 
第一步,团队负责人(通常是开发经理)提前预定好会议室,并通知参与代码评审的人员,让他们做好准备。 
第二步,在评审会上,讲解员大声阅读被评审的代码,评审人员就代码的问题给出自己的看法和意见,记录员再将这些意见记录下来。 
第三步,评审结束之后,团队负责人将评审记录以邮件的形式发出来,并督促被评审代码的编写者按照评审意见对代码进行修改。

代码评审小结 
最近,我参加了几个C语言代码的评审会,发现了代码中一些共同存在的问题,特总结下来,供相关的开发人员参考。

1.添加、修改、删除代码的时候缺少了注释说明。 
在很多开发人员看来,注释是可有可无的东西,只要实现了程序的功能即可。实际上,这种想法是不对的。对于缺少必要注释的代码,在刚编写的时候,还能够知道每行代码的作用,但是当经过了多个版本的演进之后,不要说其他人,就算是作者本人,也未必知道当初自己为何要这么编写代码。当你接手缺少注释而读起来很吃力的代码的时候,有一种想把代码原作者拉过来打一顿的冲动。不管你又没有,反正我是有的。

因此,不管工作有多忙,在编写代码的同时,我们一定要在适当的地方添加适当的注释,这也是对一个合格的编程人员的基本要求。

2.在代码关键分支处缺少了日志信息,不便于分析和排查问题。 
很多代码在“return”语句之前或else分支处没有日志信息,这使得跟踪代码流程变得比较困难,在程序出现故障的时候不便于分析和排查问题。

例如,如下代码:

if (var1 > 0)
{
    return;
}
if (var2 > 0)
{
    return;
}
if (var3 > 0)
{
    return;
}

当程序执行到这段代码而返回的时候,我们不知道到底是哪个变量大于了0,这导致我们不知从哪里入手排查问题。

正确的做法是在每个“return”语句之前,都添加详细的日志说明,如下语句所示:

if (var1 > 0)
{
    // 日志说明1
    return;
}
if (var2 > 0)
{
    // 日志说明2
    return;
}
if (var3 > 0)
{
    // 日志说明3
    return;
}

又如,如下代码:

if (var1 > 0)
{
    // 执行操作1
}
else
{
    return;
}
if (var2 > 0)
{
    // 执行操作2
}
else
{
    return;
}
if (var3 > 0)
{
    // 执行操作3
}
else
{
    return;
}

当程序执行到这段代码而返回的时候,我们不知道到底是在哪个else分支返回的。正确的做法同上,要在每个“return”语句之前,都添加详细的日志说明。

3.代码中出现了魔幻数字,不知道它们表达的意思。 
例如,如下代码:

if (var1 == 100)
{
    // 执行操作1
}
else if (var1 == 200)
{
    // 执行操作2
}
else if (var1 == 300)
{
    // 执行操作3
}
else
{
    // 执行操作4
}

在看到这段代码的时候,我们不知道代码中的100、200、300表示什么意思,只是感觉头有点晕。这类我们不知道表达什么意思的数字就统称为魔幻数字。

为了消灭魔幻数字,正确的做法是将它们用宏替代,以提高代码的可阅读性和可修改性。将上面的代码修改之后如下所示:

#define   SMALL    100
#define   MEDIUM   200
#define   BIG      300

if (var1 == SMALL)
{
    // 执行操作1
}
else if (var1 == MEDIUM)
{
    // 执行操作2
}
else if (var1 == BIG)
{
    // 执行操作3
}
else
{
    // 执行操作4
}

4.在使用字符串相关操作函数strcpy、memcpy等的时候,没有判断拷贝长度。 
在涉及到字符串相关操作的时候,大家一定注意防止操作不当而引起内存越界。如下代码没有判断拷贝长度,就容易引起了内存越界:

char src[100] = {0};
char dest[80] = {0};

strcpy(dest, src);

如上面的代码所示,当src中字符串的长度大于了80的时候,就会出现内存越界的情况,程序就会崩溃。

正确的做法是在执行拷贝操作之前,先判断字符串的长度,同时将strcpy函数替换为strncpy。修改之后的代码如下所示:

char src[100] = {0};
char dest[80] = {0};
int  len      = 0;

if (strlen(src) >= sizeof(dest)-1)
{
    len = sizeof(dest)-1;
}
else
{
    len = strlen(src);
}
strncpy(dest, src, len);

5.if…else语句的判断条件不明确,用多个变量作为多个else if的判断条件。 
例如,如下代码所示:

#define   SMALL    100
#define   MEDIUM   200
#define   BIG      300

if (var1 == SMALL)
{
    // 执行操作1
}
else if (var1 == MEDIUM)
{
    // 执行操作2
}
else if (var2 == BIG)
{
    // 执行操作3
}
else if (var3 == BIG)
{
    // 执行操作4
}
else
{
    // 执行操作5
}

在上面的代码中,if…else语句的判断条件中使用了三个不同的变量var1、var2和var3,这导致了代码阅读起来不方便,而且后续对代码的修改也容易出现错误。

正确的做法是同一级的if…else语句的判断条件中要使用相同的变量,修改之后的代码如下所示:



点击查看全文

C语言代码评审小结_第1张图片

你可能感兴趣的:(阿里云,大数据)