好记性不如烂笔头o(^▽^)o
系列的文章:
《C语言的艺术之——头文件》
《C语言的艺术之——函数》
《C语言的艺术之——标识符命令与定义》
《C语言的艺术之——变量》
C语言的艺术之——注释
C语言的艺术之——排版与格式
C语言的艺术之——安全性
C语言的艺术之——变量
1、一个变量只有一个功能,不能把一个变量用作多种用途
2、结构功能单一;不要设计面面俱到的数据结构
说明:相关的一组信息才是构成一个结构体的基础,结构的定义应该可以明确的描述一个对象,而不是一组相关性不强的数据的集合。
设计结构时应力争使结构代表一种现实事务的抽象,而不是同时代表多种。结构中的各元素应代表同一事务的不同侧面,而不应把描述没有关系或关系很弱的不同事务的元素放到同一结构中。
示例:如下结构不太清晰、合理。
typedef struct STUDENT_STRU
{
unsigned char name[32]; /* student's name */
unsigned char age; /* student's age */
unsigned char sex; /* student's sex, as follows */
/* 0 - FEMALE; 1 - MALE */
unsigned char teacher_name[32]; /* the student teacher's name */
unsigned char teacher_sex; /* his teacher sex */
} STUDENT;
若改为如下,会更合理些。
typedef struct TEACHER_STRU
{
unsigned char name[32]; /* teacher name */
unsigned char sex; /* teacher sex, as follows */
/* 0 - FEMALE; 1 - MALE */
unsigned int teacher_ind; /* teacher index */
} TEACHER;
typedef struct STUDENT_STRU
{
unsigned char name[32]; /* student's name */
unsigned char age; /* student's age */
unsigned char sex; /* student's sex, as follows */
/* 0 - FEMALE; 1 - MALE */
unsigned int teacher_ind; /* his teacher index */
} STUDENT;
3、不用或者少用全局变量
说明:单个文件内部可以使用static的全局变量,可以将其理解为类的私有成员变量。
全局变量应该是模块的私有数据,不能作用对外的接口使用,使用static类型定义,可以有效防止外部文件的非正常访问,建议定义一个STATIC宏,在调试阶段,将STATIC定义为static,版本发布时,改为空,以便于后续的打补丁等操作。
#ifdef _DEBUG
#define STATIC static
#else
#define STATIC
#endif
直接使用其他模块的私有数据,将使模块间的关系逐渐走向“剪不断理还乱”的耦合状态,这种情形是不允许的。
4、防止局部变量与全局变量同名
说明:尽管局部变量和全局变量的作用域不同而不会发生语法错误,但容易使人误解。
5、通讯过程中使用的结构,必须注意字节序
说明:通讯报文中,字节序是一个重要的问题,我司设备使用的cpu类型复杂多样,大小端、32位/64位的处理器也都有,如果结构会在报文交互过程中使用,必须考虑字节序问题。
由于位域在不同字节序下,表现看起来差别更大,所以更需要注意。
对于这种跨平台的交互,数据成员发送前,都应该进行主机序到网络序的转换;接收时,也必须进行网络序到主机序的转换。
6、严禁使用未经初始化的变量作为右值
7、在首次使用前初始化变量,初始化的地方离使用的地方越近越好
说明:未初始化变量是C和C++程序中错误的常见来源。在变量首次使用前确保正确初始化。
示例:
//不可取的初始化:无意义的初始化
int speedup_factor = 0;
if (condition)
{
speedup_factor = 2;
}
else
{
speedup_factor = -1;
}
//不可取的初始化:初始化和声明分离
int speedup_factor;
if (condition)
{
speedup_factor = 2;
}
else
{
speedup_factor = -1;
}
//较好的初始化:使用默认有意义的初始化
int speedup_factor = -1;
if (condition)
{
speedup_factor = 2;
}
//较好的初始化使用?:减少数据流和控制流的混合
int speedup_factor = condition?2:-1;
//较好的初始化:使用函数代替复杂的计算流
int speedup_factor = ComputeSpeedupFactor();
8、明确全局变量的初始化顺序,避免跨模块的初始化依赖
说明:系统启动阶段,使用全局变量前,要考虑到该全局变量在什么时候初始化,使用全局变量和初始化全局变量,两者之间的时序关系,谁先谁后,一定要分析清楚,不然后果往往是低级而又灾难性的。
9、尽量减少没有必要的数据类型默认转换与强制转换
说明:当进行数据类型强制转换时,其数据的意义、转换后的取值等都有可能发生变化,而这些细节若考虑不周,就很有可能留下隐患。
示例:如下赋值,多数编译器不产生告警,但值的含义还是稍有变化。
char ch;
unsigned short int exam;
ch = -1;
exam = ch; // 编译器不产生告警,此时exam为0xFFFF。