当前位置:首页 > 代码规范
6. 函数、过程
1. 对所调用函数的错误返回码要仔细、全面地处理。 2. 明确函数功能,精确(而不是近似)地实现函数设计。
3. 在同一项目组应明确规定对接口函数参数的合法性检查应由函数的调用者
负责还是由接口函数本身负责,缺省是由函数调用者负责。
说明:对于模块间接口函数的参数的合法性检查这一问题,往往有两个极端现象,即:要么是调用者和被调用者对参数均不作合法性检查,结果就遗漏了合法性检查这一必要的处理过程,造成问题隐患;要么就是调用者和被调用者均对参数进行合法性检查,这种情况虽不会造成问题,但产生了冗余代码,降低了效率。
4. 防止将函数的参数作为工作变量。
说明:将函数的参数作为工作变量,有可能错误地改变参数内容,所以很危险。对必须改变的参数,最好先用局部变量代之,最后再将该局部变量的内容赋给该参数。
示例:下函数的实现不太好。
void sum_data( unsigned int num, int *data, int *sum ) {
unsigned int count;
*sum = 0;
for (count = 0; count < num; count++) {
*sum += data[count]; // sum成了工作变量,不太好。 } }
若改为如下,则更好些。
void sum_data( unsigned int num, int *data, int *sum ) {
unsigned int count ; int sum_temp;
sum_temp = 0;
for (count = 0; count < num; count ++) {
sum_temp += data[count]; }
*sum = sum_temp; }
5. 函数的规模尽量限制在200行以内。
说明:不包括注释和空格行。
6. 一个函数仅完成一件功能。 7. 为简单功能编写函数。
说明:虽然为仅用一两行就可完成的功能去编函数好象没有必要,但用函数可使功能明确化,增加程序可读性,亦可方便维护、测试。
示例:如下语句的功能不很明显。 value = ( a > b ) ? a : b ;
改为如下就很清晰了。 int max (int a, int b) {
return ((a > b) ? a : b); }
value = max (a, b);
或改为如下。
#define MAX (a, b) (((a) > (b)) ? (a) : (b))
value = MAX (a, b);
8. 不要设计多用途面面俱到的函数。
说明:多功能集于一身的函数,很可能使函数的理解、测试、维护等变得困难。
9. 函数的功能应该是可以预测的,也就是只要输入数据相同就应产生同样的输
出。
说明:带有内部“存储器”的函数的功能可能是不可预测的,因为它的输出可能取决于内部存储器(如某标记)的状态。这样的函数既不易于理解又不利于测试和维护。在C/C++语言中,函数的static局部变量是函数的内部存储器,有可能使函数的功能不可预测,然而,当某函数的返回值为指针类型时,则必须是STATIC的局部变量的地址作为返回值,若为AUTO类,则返回为错针。
示例:如下函数,其返回值(即功能)是不可预测的。 unsigned int integer_sum( unsigned int base ) {
unsigned int index;
static unsigned int sum = 0; // 注意,是static类型的。 // 若改为auto类型,则函数即变为可预测。 for (index = 1; index <= base; index++) {
sum += index; }
return sum; }
10. 函数名应准确描述函数的功能。使用动宾词组为执行某操作的函数命名。如
果是OOP方法,可以只有动词(名词是对象本身)。
示例:参照如下方式命名函数。
void print_record( unsigned int rec_ind ) ; int input_record( void ) ;
unsigned char get_current_color( void ) ;
11. 减少函数本身或函数间的递归调用。
说明:递归调用特别是函数间的递归调用(如A->B->C->A),影响程序的可理解性;递归调用一般都占用较多的系统资源(如栈空间);递归调用对程序的测试有一定影响。故除非为某些算法或功能的实现方便,应减少没必要的递归调用。
12. 对于提供了返回值的函数,在引用时最好使用其返回值。
共分享92篇相关文档