C语言的艺术之——函数
好记性不如烂笔头o(^▽^)o C语言的艺术之函数
1、1个函数仅完成1件功能
案例:realloc char *buffer = (char *)malloc(XXX_SIZE);
.....
buffer = (char *)realloc(buffer,NEW_SIZE); ??如果没有足够可用的内存用来完成重新分配,函数返回为NULL,致使buffer原来指向的内存被丢失。 2、重复代码应当尽量提炼成函数
??项目组应当使用代码重复度检查工具,在延续集成环境中延续检查代码重复度指标变化趋势,并对新增重复代码及时重构。当1段代码重复两次时,即应斟酌消除重复,当代码重复超过3次时,应当立刻着手消除重复。 3、避免函数太长,新增函数尽可能不超过50行(非空非注释行)
太长的函数常常意味着函数功能不单1,过于复杂。 4、避免函数的代码块嵌套过深,新增函数的代码块嵌套不超过4层
??函数的代码块嵌套深度指的是函数中的代码控制块(例如:if、for、while、switch等)之间相互包括的深度。每级嵌套都会增加浏览代码时的脑力消耗,由于需要在头脑里保护1个“栈”(比如,进入条件语句、进入循环……)。应当做进1步的功能分解,从而避免使代码的浏览者1次记住太多的上下文。优秀代码参考值:[1,4]。 5、可重入函数应避免使用同享变量;若需要使用,则应通过互斥手段(关中断、信号量)对其加以保护
??编写C语言的可重入函数时,不应使用static局部变量,否则必须经过特殊处理,才能使函数具有可重入性。 int g_exam;
unsigned int example( int para )
{
unsigned int temp;
g_exam = para; // (**)
temp = square_exam ( );
return temp;
} ??此函数若被多个线程调用的话,其结果多是未知的,由于当(**)语句刚履行完后,另外1个使用本函数的线程可能正好被激活,那末当新激活的线程履行到此函数时,将使g_exam赋于另外一个不同的para值,所以当控制重新回到“temp =square_exam ( )”后,计算出的temp极可能不是料想中的结果。此函数应以下改进。 int g_exam;
unsigned int example( int para )
{
unsigned int temp;
[申请信号量操作] // 若申请不到“信号量”,说明另外的进程正处于
g_exam = para; //给g_exam赋值并计算其平方进程中(即正在使用此
temp = square_exam( ); // 信号),本进程必须等待其释放信号后,才可继
[释放信号量操作] // 续履行。其它线程必须等待本线程释放信号量后
// 才能再使用本信号。
return temp;
} 6、对参数的合法性检查,由调用者负责还是由接口函数负责,应在项目组/模块内应统1规定。缺省由调用者负责
7、对函数的毛病返回码要全面处理
8、设计高扇入,公道扇出(小于7)的函数
??扇出过大,表明函数过分复杂,需要控制和调和过量的下级函数;而扇出太小,例如:总是1,表明函数的调用层次可能过量,这样不利于程序浏览和函数结构的分析,并且程序运行时会对系统资源如堆栈空间等造成压力。通常函数比较公道的扇出(调度函数除外)通常是3~5。 9、废弃代码(没有被调用的函数和变量)要及时清除说明:程序中的废弃代码不但占用额外的空间,而且还常常影响程序的功能与性能,极可能给程序的测试、保护等造成没必要要的麻烦。 10、函数不变参数使用const
11、函数应避免使用全局变量、静态局部变量和I/O操作,不可避免的地方应集中使用
12、检查函数所有非参数输入的有效性,如数据文件、公共变量等
13、函数的参数个数不超过5个
14、除打印类函数外,不要使用可变长参函数
15、在源文件范围内声明和定义的所有函数,除非外部可见,否则应当增加static关键字
??建议定义1个STATIC宏,在调试阶段,将STATIC定义为static,版本发布时,改成空,以便于后续的打热补钉等操作。 #ifdef _DEBUG
#define STATIC static
#else
#define STATIC
#endif (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |