三、2022.12.12
-
规则4——字符集
- 规则 4.1(强制): 只能使用 ISO C 标准中定义的 escape 序列
- 规则 4.2(强制): 不能使用三字母词(trigraphs)
例如字符串 “(Date should be in the form ??-??-??)”将不会表现为预期的那样,实际上它被编译器解释为“(Date should be in the form ~~)”这个有点意思
-
规则5——标识符
- 规则 5.1(强制): 标识符(内部的和外部的)的有效字符不能多于 31
- 规则 5.2(强制): 具有内部作用域的标识符不应使用与具有外部作用域的标识符相同的名称,这会隐藏了外部标识符
int16_t i; { int16_t i; /* This is a different variable */ /* This is not compliant */ i = 3; /* It could be confusing as to which I this refers */ }
-
规则 5.3(强制): typedef 的名字应当是唯一的标识符
-
规则 5.4(强制): 标签(tag)名称必须是唯一的标识符
struct stag { uint16_t a; uint16_t b; }; struct stag a1 = { 0, 0 }; /* Compliant – compatible with above */ union stag a2 = { 0, 0 }; /* Not compliant – not compatible with previous declarations */
补充说明:tag的用法
struct demo_tag { char a; short b; int c; } var1; struct demo_tag var2; //上述代码实现了两个结构体变量的定义,但是第二种方式采用了结构体的tag用以代替了结构体的描述。 //这种定义方式每次需要些struct关键字,因为tag只是代表了结构体的描述信息.
-
规则 5.5(建议): 具有静态存储期的对象或函数标识符不能重用
由于编译器能够理解这一点而且决不会发生混淆,那么对用户来说就存在着把不相关的变量以相同名字联系起来的可能性 -
规则 5.6(建议): 一个命名空间中不应存在与另外一个命名空间中的标识符拼写相同的标识符,除了结构和联合中的成员名字
命名空间与作用域(scope)是不同的,本规则不考虑作用域。例如,ISO C 允许在一个作用域内为标签(tag)和 typedef 使用相同的标识符(vector),如下:typedef struct vector //此处vector相当于tag { uint16_t x ; uint16_t y ; uint16_t z ; } vector ; //此处vector相当于tag结构体类型的别名
不合适的例子如下:
struct { int16_t key ; int16_t value ; } record ; int16_t value; /* Rule violation – 2nd use of value */ record.key = 1; value = 0; /* should have been record.value */
-
规则 5.7(建议): 不能重用标识符名字
总结:本规则与5.2-5.6一起使用,其核心是保证变量名尽量不重用,尤其是在不同的命名空间中,避免出现过程中的赋值错误,导致意想不到的问题发生;同时可以是程序的可读性更强
-
规则6——类型
- 规则 6.1(强制): 单纯的 char 类型应该只用做存储和使用字符值
- 规则 6.2(强制): signed char 和 unsigned char 类型应该只用做存储和使用数字值
有三种不同的 char 类型:(单纯的)char、unsigned char、signed char。unsigned char 和 signed
char 用于数字型数据,char 用于字符型数据。单纯 char 类型的符号是实现定义的,不应依赖。单纯 char 类型所能接受的操作只有赋值和等于操作符(=、==、!=) - 规则 6.3(建议): 应该使用指示了大小和符号的 typedef 以代替基本数据类型
- 规则 6.4(强制): 位域只能被定义为 unsigned int 或 singed int 类型
- 规则 6.5(强制): unsigned int 类型的位域至少应该为 2 bits 长度