C语言编程规范(二)

5.标识符命名规则

规则 5-1 标识符的命名要清晰、明了,有明确含义,同时使用完整的单词或大家基本可以理解的缩写,避免使人产生误解。

说明:较短的单词可通过去掉“元音”形成缩写;较长的单词可取单词的头几个字母形成。
缩写;一些单词有大家公认的缩写。
示例:如下单词的缩写能够被大家基本认可。
temp 可缩写为 tmp ;
flag 可缩写为 flg ;
statistic 可缩写为 stat ;
increment 可缩写为 inc ;
message 可缩写为 msg ;

规则 5-2 对自定义数据类型进行恰当命名,使它成为自描述性的,以提高代码可读性。注意其命名方式在同一产品中的统一,比如:int32_t, int64_t, int8_t, uint64_t, uint32_t, uint8_t, char。
说明:使用自定义类型,可以弥补编程语言提供类型少、信息量不足的缺点,并能使程序清晰、简洁。
示例:可参考如下方式声明自定义数据类型。
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;

规则 5-3 对使用typedef定义的结构体,需要在其名称后加_t;对使用typedef定义的枚举,需要在其名称后加_e。

规则 5-4 命名规范必须与所使用的系统风格保持一致,并在同一项目中统一,比如采用UNIX的全小写加下划线的风格或大小写混排的方式,不要使用大小写与下划线混排的方式,用作特殊标识如标识成员变量或全局变量的m_和g_,其后加上大小写混排的方式是允许的。
示例: Add_User不允许,add_user、AddUser、m_AddUser允许。

规则 5-5 程序中不要出现仅靠大小写区分的相似的标识符。

规则 5-6 程序中不要出现标识符完全相同的局部变量和全局变量,尽管两者的作用域不同而不会发生语法错误,但会使人误解。要求全局变量添加g_前缀。

规则 5-7 变量的名字应当使用“名词”或者“形容词+名词”。
例如:float value;
float oldValue;

规则 5-8 全局函数的名字应当使用“动词”或者“动词+名词”(动宾词组)。类的成员函数应当只使用“动词”,被省略掉的名词就是对象本身。
例如:DrawBox(); // 全局函数

6.表达式和基本语句

规则 6-1不要过分依赖C 表达式中的运算符优先规则。
括号的使用除了可以覆盖缺省的运算符优先级以外,还可以用来强调所使用的运算符。使用相当复杂的C运算符优先级规则很容易引起错误,那么这种方法就可以帮助避免这样的错误,并且可以使得代码更为清晰可读。然而,过多的括号会分散代码使其降低了可读性。
下面的方针给出了何时使用括号的建议:
1、赋值运算符的右手操作数不需要使用括号,除非右手端本身包含了赋值表达式:

x = a + b; /* acceptable */
x = (a + b); /* ( ) not required */

2、 一元运算符的操作数不需要使用括号:

扫描二维码关注公众号,回复: 10403702 查看本文章
x = a * -1; /* acceptable */
x = a * (-1); /* ( ) not required */

3、否则,二元和三元运算符的操作数应该是cast-expressions,除非表达式中所有运算符是相同的。

x = a + b + c; /* acceptable, but care needed */
x = f ( a + b, c ); /* no ( ) required for a + b */
if (a && b && c) /* acceptable */
x = (a + b) - (c + d);/* acceptable */
x = (a * 3) + c + d; /* acceptable */
x = (uint16_t) a + b; /* no need for ( ( uint16_t ) a ) */

4、即使所有运算符都是相同的,也可以使用括号控制运算的次序。某些运算符(如,加法和乘法)在代数学上结合律的,而在C 中未必如此。类似地,涉及混合类型的整数运算(许多规则不允许)因为整数提升的存在可以产生不同的结果。下面的例子是按照16 位的实现写成的,它描述了加法不是结合的以及表达式结构清晰的重要性:

uint16_t a = 10;
uint16_t b = 65535;
uint32_t c = 0;
uint32_t d;
d = (a + b) + c; /* d is 9; a + b wraps modulo 65536 */
d = a + (b + c); /* d is 65545 */

规则 6-2 变量的自加、自减运算符需要单独占一行。

下面的条款告诉我们对运算次序的依赖是如何发生的,并由此帮助我们采纳本规则。
1、自增或自减运算符
做为能产生错误的例子,考虑
x = b[i] + i++;
根据b[i] 的运算是先于还是后于i ++ 的运算,表达式会产生不同的结果。把增值运算做为单独的语句,可以避免这个问题。那么:
x = b[i] + i;
i ++;
2、函数参数
函数参数的运算次序是未指定的。
x = func ( i++, i);
根据函数的两个参数的运算次序不同,表达式会给出不同的结果。

规则 6-3 逻辑运算符 && 或 | | 的右手操作数不能包含副作用。
C 当中存在这样的情况,表达式的某些部分不会被计算到。如果这些子表达式具有副作用,那么副作用可能会发生也可能不会发生,这依赖于其他子表达式的值。
例如:

if ( ishigh && ( x == i++ ) ) /* Not compliant */

规则 6-4 在if语句中不可将布尔变量直接与TRUE、FALSE 或者1、0 进行比较。
假设布尔变量名字为flag,它与零值比较的标准if 语句如下:
if (flag) // 表示flag 为真
if (!flag) // 表示flag 为假

规则 6-5 在if语句中应当将整型变量用“==”或“!=”直接与0 比较。
不可模仿布尔变量的风格而写成:
if (value) // 会让人误解value 是布尔变量
if (!value)

规则 6-6 在if语句不可将浮点变量用“双=”或“!=”与任何数字比较。 千万要留意,无论是float 还是double 类型的变量,都有精度限制。所以一定要避免将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”形式。

规则 6-7 在if语句中应当将指针变量用“==”或“!=”与NULL 比较。

规则 6-8 if语句尽量加上else分支,对没有else分支的语句要小心对待。

规则 6-9 比较语句中建议常量作左值!!!
示例:比如if (5 == i), 而不是i == 5, 预防 == 写成 = 的错误。

规则 6-10 在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU 跨切循环层的次数。
推荐风格:

for (col=0; col<5; col++ )
{
for (row=0; row<100; row++)
{
sum = sum + a[row][col];
}
}
不推荐风格:
for (row=0; row<100; row++)
{
for (col=0; col<5; col++ )
{
sum = sum + a[row][col];
}
}

规则 6-11 应限制多重循环的嵌套深度,建议控制在5层以内。

规则 6-12 每个case 语句的结尾不要忘了加break,否则将导致多个分支重叠。如果有意使多个分支重叠,也需要增加注释说明。

规则 6-13 不要忘记最后那个default 分支。即使程序真的不需要default 处理,也应该保留语句default : break;。

规则 6-14 goto 语句经常带来错误或隐患。它可能跳过了某些对象的构造、变量的初始化、重要的计算等语句,并且会破坏结构化设计风格。本规则主张少用、慎用goto 语句

规则 6-15 代码分支都使用大括号{}括起来,包括只有一行代码的情况!!

发布了56 篇原创文章 · 获赞 75 · 访问量 30万+

猜你喜欢

转载自blog.csdn.net/qq_44710568/article/details/105264289