函数要注意的编码风格

对于函数人们很少能注意到这一点,认为无所谓,其实不然,好的代码风格可以增加代码的可读性

【规则6-1】 每一个函数都必须有注释,即使函数短到可能只有几行。头部说明需要包扩括

含包含的内容和次序如下:
/**************************************************************
* Function Name : nucFindThread
* Create Date : 2000/01/07
* Author/Corporation : your name/your company name
*
* Description : Find a proper thread in thread array.
* If it’s a new then search an empty.
*
* Param : ThreadNo: someParam description
* ThreadStatus: someParam description
*
* Return Code : Return Code description,eg:
ERROR_Fail: not find a thread
ERROR_SUCCEED: found
*
* Global Variable : DISP_wuiSegmentAppID
* File Static Variable : naucThreadNo
* Function Static Variable : None
*
*————————————————————————
* Revision History
* No. Date Revised by Item Description
* V0.5 2008/01/07 your name … …
**************************************************************/
static unsigned char nucFindThread(unsigned char ThreadNo,unsigned char ThreadStatus)
{

}

【规则6-2】 】每个函数定义结束之后以及每个文件结束之后都要加一个或若干个空行。

例如:
/**************************************************************
* ………
* Function1 Description
* ………
**************************************************************/
void Function1(……)
{

}
//Blank Line
/**************************************************************
* ………
* Function2 Description
* ………
**************************************************************/
void Function2(……)
{

}
//Blank Line
/**************************************************************
* ………
* Function3 Description
* ………
**************************************************************/
void Function3(……)
{

}
//Blank Line

【规则6-3】 】在一个函数体内,变量定义与函数语句之间要加空行。

例如:
/**************************************************************
* ………
* Function Description
*………
**************************************************************/
void Function1()
{
int n;
//Blank Line
statement1
…….
}

【规则6-4】 】逻揖上密切相关的语句之间不加空行,其它地方应加空行分隔。

例如:
//Blank Line
while (condition)
{
statement1;
//Blank Line
if (condition)
{
statement2;
}
else
{
statement3;
}
//Blank Line
statement4
}

【规则6-5】 】复杂的函数中,在分支语句,循环语句结束之后需要适当的注释,方便区

分各分支或循环体
while (condition)
{
statement1;
if (condition)
{
for(condition)
{
Statement2;
}//end “for(condition)”
}
else
{
statement3;
}//”end if (condition)”
statement4
}//end “while (condition)”
【规则6-6】 】修改别人代码的时候不要轻易删除别人的代码,应该用适当的注释方式,
例如:
while (condition)
{
statement1;
//
//your name , 2008/01/07 delete
//if (condition)
//{
// for(condition)
// {
// Statement2;
// }
//}
//else
//{
// statement3;
//}

///
// your name , 2000/01/07 add

new code

///
statement4
}

【规则6-7 】用缩行显示程序结构,使排版整齐,缩进量统一使用4个字符(不使用TAB

缩进)。
每个编辑器的TAB键定义的空格数不一致,可能导致在别的编辑器打开你的代码乱成一
团糟。

【规则6-8】 】在函数体的开始、结构/联合的定义、枚举的定义以及循环、判断等语句中

的代码都要采用缩行。

【规则6-9】 】同层次的代码在同层次的缩进层上。

例如:
提倡的的风格 不提倡的风格
void Function(int x)
{
//program code
}
void Function(int x)
{
//program code
}
struct tagMyStruct struct tagMyStruct{

【规则6-10 】代码行最大长度宜控制在80 个字符以内,较长的语句、表达式等要分成

多行书写。

【规则6-11】 】长表达式要在低优先级操作符处划分新行,操作符放在新行之首(以便突

出操作符)。拆分出的新行要进行适当的缩进,使排版整齐,语句可读。
例如:
if ((very_longer_variable1 >= very_longer_variable12)
&& (very_longer_variable3 <= very_longer_variable14)
&& (very_longer_variable5 <= very_longer_variable16))
{
dosomething();
}
for (very_longer_initialization;
very_longer_condition;
very_longer_update)
{
dosomething();
}

【规则6-12】 】如果函数中的参数较长,则要进行适当的划分。

例如:
void function(float very_longer_var1,
float very_longer_var2,
float very_longer_var3)

【规则6-13】 】用正确的反义词组命名具有互斥意义的变量或相反动作的函数等。

例如:
int aiMinValue;
int aiMaxValue;
int niSet_Value(⋯);
int niGet_Value(⋯);

【规则6-14】 】如果代码行中的运算符比较多,用括号确定表达式的操作顺序,避免使用

默认的优先级。
{
int a;
int b;
int c;
};
int a;
int b;
int c;
};
if (condition)
{
//program code
}
else
{
//program code
}
if (condition){
//program code
}else{
//program code
}
例如:
leap_year = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);

【规则6-15】 】不要编写太复杂的复合表达式。

例如:
i = a >= b && c < d && c + f <= g + h; 复合表达式过于复杂

【规则6-16】 】不要有多用途的复合表达式。

例如:
d = (a = b + c) + r;
该表达式既求a 值又求d 值。应该拆分为两个独立的语句:
a = b + c;
d = a + r;

【建议6-17】 】尽量避免含有否定运算的条件表达式。

例如:
如: if (!(num >= 10))
应改为: if (num < 10)

【规则6-18】 】参数的书写要完整,不要贪图省事只写参数的类型而省略参数名字。如果

函数没有参数,则用void 填充。
例如:
6.2,函数设计的一般原则和技巧

【规则6-19】 】原则上尽量少使用全局变量,因为全局变量的生命周期太长,容易出错,

也会长时间占用空间.各个源文件负责本身文件的全局变量,同时提供一对对外函数,方
便其它函数使用该函数来访问变量。比如:niSet_ValueName(⋯);niGet_ValueName(⋯);
不要直接读写全局变量,尤其是在多线程编程时,必须使用这种方式,并且对读写操作
加锁。

【规则6-20】 】参数命名要恰当,顺序要合理。

例如编写字符串拷贝函数str_copy,它有两个参数。如果把参数名字起为str1 和str2,例

void str_copy (char *str1, char *str2);
那么我们很难搞清楚究竟是把str1 拷贝到str2 中,还是刚好倒过来。
可以把参数名字起得更有意义,如叫strSource 和strDestination。这样从名字上就可
以看出应该把strSource 拷贝到strDestination。
还有一个问题,这两个参数那一个该在前那一个该在后?参数的顺序要遵循程序员
的习惯。一般地,应将目的参数放在前面,源参数放在后面。
提倡的风格 不提倡的风格
void set_value(int width, int height);
float get_value(void);
void set_value (int, int);
float get_value ();
如果将函数声明为:
void str_copy (char *strSource, char *strDestination);
别人在使用时可能会不假思索地写成如下形式:
char str[20];
str_copy (str, “Hello World”); 参数顺序颠倒

【规则6-21】 】如果参数是指针,且仅作输入参数用,则应在类型前加const,以防止该

指针在函数体内被意外修改。
例如:
void str_copy (char *strDestination,const char *strSource);

【规则6-22 】不要省略返回值的类型,如果函数没有返回值,那么应声明为void 类型。

如果没有返回值,编译器则默认为函数的返回值是int类型的。

【规则6-23】 】在函数体的“入口处”,对参数的有效性进行检查。尤其是指针参数,尽

量使用assert宏做入口校验,而不使用if语句校验。(关于此问题讨论,详见指针与数组那章。)

【规则6-24 】return 语句不可返回指向“栈内存”的“指针”,因为该内存在函数体结

束时被自动销毁。例如:
char * Func(void)
{
char str[30];

return str;
}
str 属于局部变量,位于栈内存中,在Func 结束的时候被释放,所以返回str 将导致错误。

【规则6-25 】函数的功能要单一,不要设计多用途的函数。微软的Win32 API就是违反
【规则6-26 】函数体的规模要小,尽量控制在80 行代码之内。
【建议6-27】 】相同的输入应当产生相同的输出。尽量避免函数带有“记忆”功能。

带有“记忆”功能的函数,其行为可能是不可预测的,因为它的行为可能取决于某种
“记忆状态“。这样的函数既不易理解又不利于测试和维护。在C 语言中,函数的static
局部变量是函数的“记忆”存储器。建议尽量少用static 局部变量,除非必需。

【建议6-28 】避免函数有太多的参数,参数个数尽量控制在4个或4个以内。如果参数太

多,在使用时容易将参数类型或顺序搞错。微软的Win32 API就是违反本规则的典型,
其函数的参数往往七八个甚至十余个。比如一个CreateWindow函数的参数就达11个之
多。

【建议6-29】 】尽量不要使用类型和数目不确定的参数。

C 标准库函数printf 是采用不确定参数的典型代表,其原型为:
int printf(const chat *format[, argument]⋯);
这种风格的函数在编译时丧失了严格的类型安全检查。

【建议6-30】 】有时候函数不需要返回值,但为了增加灵活性如支持链式表达,可以附加

返回值。例如字符串拷贝函数strcpy 的原型:
char *strcpy(char *strDest,const char *strSrc);
strcpy 函数将strSrc 拷贝至输出参数strDest 中,同时函数的返回值又是strDest。这样做
并非多此一举,可以获得如下灵活性:
char str[20];
int length = strlen(strcpy(str, “Hello World”) );

【建议6-31】 】不仅要检查输入参数的有效性,还要检查通过其它途径进入函数体内的变

量的有效性,例如全局变量、文件句柄等。

【规则6-32】 】函数名与返回值类型在语义上不可冲突。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值