C/C++编程规范
一.编写可重入函数时,应注意局部变量的使用,如编写C/C++语言的可重入函数时,应使用auto即缺省态局部变量或寄存器变量。
编写C/C++语言的可重入函数时,不应使用static局部变量,否则必须经过特殊处理,才能使函数具有可重入性。static局部变量相当于全局变量,如果两个进程同时访问该函数则会导致错误。
二.编写可重入函数时,若使用全局变量,则应通过关中断,信号量(即P,V操作)等手段对其加以保护。
如果对所使用的全局变量不加以保护,则此函数就不具有可重入性,即当多个进程调用此函数时,很有可能使有关全局变量变为不可知状态。
三.设计高扇入,合理扇出(小于7)的函数
扇出是指一个函数直接调用其他函数的数目,而扇入是指有多少上级函数调用它。
扇出过大,表明函数过分复杂,需要控制和协调过多的下级函数;而扇出过小,如总是1,表明函数的调用层次可能过多,这样不利于程序阅读和函数结构的分析,并且程序运行时会对系统资源如堆栈空间等造成压力。函数较合理的扇出(调度函数除外)通常是3-5.扇出太大,一般是由于缺乏中间层次,可适当增加中间层次的函数,扇出太小,可把下级函数进一步分解多个函数,或合并到上级函数中。当然分解或合并函数时,不能改变要实现的功能,也不能违背函数间的独立性。
扇入越大,表明使用此函数的上级函数越多,这样的函数使用效率高,但不能违背函数间的独立性而单纯地追求高扇入。公共模块中的函数及底层函数应该有较高的扇入。
较良好的软件结构通常是顶层函数的扇出较高,中层函数的扇出较少,而底层函数则扇入到公共模块中。
四.在多重循环中,应将最忙的循环放在最内层。从而减少CPU切入循环层的次数。
五.避免循环体内含判断语句,应将循环语句置于判断语句的代码块中。
目的是减少判断次数,一般情况,与循环变量无关的判断语句可以以到循环体外,而有关的则不可以。
如:
如下代码效率稍低:
for (ind = 0; ind < MAX_RECT_NUMBER; ind++) {
if (data_type == RECT_AREA) {
area_sum += rect_area[ind];
} else {
rect_length_sum += rect[ind].length;
rect_width_sum += rect[ind].width;
}
}
因为判断语句与循环变量无关,故可如下改进,以减少判断次数。
if (data_type == RECT_AREA) {
for (ind = 0; ind < MAX_RECT_NUMBER; ind++) {
area_sum += rect_area[ind];
}
} else {
for (ind = 0; ind < MAX_RECT_NUMBER; ind++) {
rect_length_sum += rect[ind].length;
rect_width_sum += rect[ind].width;
}
}
六.尽量用乘法或其他方法代替除法,特别是浮点运算中的除法。
说明:浮点运算除法要占用较多的CPU资源。
如:如下表达式运算可能要占据较多CPU资源。
#define PAI 3.1416
radius = circle_length / (2*PAI)
应如下把浮点除法改为浮点乘法。
//编译器编译时,将生成具体浮点数
#define PAI_RECIPROCAL (1/3.1416)
radius = circle_length * PAI_RECIPROCAL / 2;
七.if语句尽量加上else分支,对没有else分支的语句要小心对待;switch语句必须有default分支。在使用switch和case时把正常情况放在前面,而把异常情况放在后面
default:
break;
八.用宏定义表达式时,要使用完备的括号。
#define RECTANGLE_AREA(a, b) ((a) * (b))
九.将宏多定义的多条表达式放在大括号中。
#define INIT_RECT_VALUE(a, b) \
{\
a = 0;\
b = 0;\
}
十.使用宏时,不允许参数发生变化
示例:
如下用法可能导致错误。
#define SQUARE(a) ((a)*(a))
int a = 5;
int b;
b = SQUARE(a++); //结果:a = 7,即执行了两次增1
正确的用法是:
b = SQUARE(a);
a++; // 结果: a = 6, 即只执行了一次增1