C语言易错点
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
变量、结构
6、当声明用于分布式环境或不同CPU间通信环境的数据结构时,必须考虑机器的 、当声明用于分布式环境或不同 间通信环境的数据结构时, 间通信环境的数据结构时 字节顺序、 字节顺序、使用的位域及字节对齐等问题 。 typedef struct EXAMPLE_STRU { unsigned short valid; unsigned int set_flg1; unsigned short set_flg2; } EXAMPLE; 考虑到4字节对齐的问题,应将该结构定义为: typedef struct EXAMPLE_STRU { unsigned short valid; unsigned short set_flg2; unsigned int set_flg1; } EXAMPLE;
变量、结构
5、若变量是字符串,需要将数组大小定义为指定长度加1的形式。 若变量是字符串,需要将数组大小定义为指定长度加 的形式 的形式。 若变量是字符串 [示例] 常用的写法 新增数组最大长度为32 readFileName[32]; 标准写法: 新增数组最大长度为32, 先定义一个长度的宏#define MAX_FILE_NAME_LEN 32, 然后定义参数readFileName[MAX_FILE_NAME_LEN + 1] 那么,为什么要用这种模式呢? 主要有两个优点,首先,使用宏定义,可以方便后期修改数组大小,只要修改宏定义 就可以修改所有相关的数据;其次,宏定义+1,为的就是保证数组在存放字符串的时 候有结束符。
表达式和基本语句
4、常量要放在 的左边。 常量要放在==的左边 常量要放在 的左边。 [示例]:这是大家比较习惯的写法。 if (data_type == RECT_AREA) { area_sum += rect_area[ind]; } 但是这是一种容易犯错的写法,为什么呢?你看下面这种错误: if (data_type = RECT_AREA) { area_sum += rect_area[ind]; } 看出不同了吗?就是“==”少了一个“=”号,这个错误很难查,编译器不会报错, 普通的调试和测试也不一定会出错,所以这种隐藏的错误很容易被漏过去,所以我 们采用下面这种写法: if (RECT_AREA == data_type) { area_sum += rect_area[ind]; }
排版规则
和空格相关的问题也是比较多的,因为这和很多人的编程习惯不同,所以有很多人都 会不自觉的犯错。 [示例]: (1) 逗号、分号只在后面加空格。 Fun(a, b, c); (2)比较操作符, 赋值操作符“=”、 “+=”,算术操作符“+”、“%”,逻辑操作符“&&”、“&”, 位域操作符"<<"、"^"等双目操作符的前后加空格。 if (current_time >= MAX_TIME_VALUE) a = b + c; a *= 2; a = b ^ 2; (3)"!"、"~"、"++"、"--"、"&"(地址运算符)等单目操作符前后不加空格。 *p = 'a'; // 内容操作"*"与内容之间 flag = !isEmpty; // 非操作"!"与内容之间 p = &mem; // 地址操作"&" 与内容之间 i++; // "++","--"与内容之间 (4)"->"、"."前后不加空格。 p->id = pid; // "->"指针前后不加空格 (5) if、for、while、switch等与后面的括号间应加空格,使if等关键字更为突出、明显。 if (a >= b && c > d)
变量、结构
易出错的地方如下: 1、严禁局部变量与全局变量同名。 严禁局部变量与全局变量同名。 严禁局部变量与全局变量同名 2、严禁使用未经初始化的变量作为右值。 、严禁使用未经初始化的变量作为右值。 3、全局变量的读取 赋值应尽量放在一处处理,若多处使用应互斥保护。 赋值应尽量放在一处处理, 、全局变量的读取/赋值应尽量放在一处处理 若多处使用应互斥保护。 A、编写可重入函数时,若使用全局变量,则应通过关中断、信号量(即P、V 操作)等手段对其加以保护。 B、构造仅有一个模块或函数可以修改、创建,而其余有关模块或函数只访问的 全局变量,防止多个不同模块或函数都可以修改、创建同一全局变量的现象。 C、当向全局变量传递数据时,要十分小心,防止赋与不合理的值或越界等现 象发生。 A、 semTake(globalMSem, WAIT_FOREVER); pDevCfgParam->periNum = ntohl(pManageCfg->periNum); semGive(globalMSem);
命名规则
命名规则可以说是比较复杂的,但也可以说是最简单的。为什么呢? 因为我们之所以要求命名符合规则,主要是为了让别人可以更方便的看懂你的代 码,但是要达成这个效果,遵守命名规则并不是唯一的方法,更简单的方法就是 加注释,只要你的注释可以让人清楚明白的知道这个变量的意义,那么也能达到 目的。 在这个方面,最容易犯错的就是这条规则: 变量命名要有具体含义外,还能表明变量类型、数据类型等, 变量命名要有具体含义外,还能表明变量类型、数据类型等,禁止取单个字符 ),但 等单个字符作为局部循环变量是允许的。 (如i、j、k…),但i、j、k等单个字符作为局部循环变量是允许的。 、、 ), 、 、 等单个字符作为局部循环变量是允许的 很多人在使用变量的时候都比较随意,特别是i、j、k这几个用的比较顺手的变量, 所以很多人都会不自觉的犯错,这个大家要注意。
C语言易错点
编制 时间 章浙锋 2011年07月21日
内容概述
排版 注释 命名规则 表达式和基本语句 变量、结构 函数、过程 内存管理 宏 其它
排版Baidu Nhomakorabea误
排版主要是为了让代码整齐好看,有人说我写的代码我觉得挺好看的,而且自己 也写习惯了,为什么要按照规范来写? 因为在公司里不是一个人负责一套代码,而是大家合作,如果每个人都有自己的 风格,那么这套代码就会杂乱不堪,大家看起来很头痛,同时也影响工作效率。 排版方面的错误,最常见的是“{}”的相关错误。大家看下面几段代码: if (NULL == pUserCR) return; for (...) { ... // program code } if (...) { ... // program code } void example_fun( void ) { ... // program code }
表达式和基本语句
表达式和基本语句中容易出错的地方不少,比如: 1、避免使用不易理解的数字,用有意义的标识来替代。涉及物理状态或者含有物 避免使用不易理解的数字, 避免使用不易理解的数字 用有意义的标识来替代。 理意义的常量,不应直接使用数字,必须用有意义的枚举或宏来代替。 理意义的常量,不应直接使用数字,必须用有意义的枚举或宏来代替。 [示例]:如下的程序可读性差。 if (0 == Trunk[index].trunk_state ) { Trunk[index].trunk_state = 1; ... // program code } 应改为如下形式: #define TRUNK_IDLE 0 #define TRUNK_BUSY 1 if (TRUNK_IDLE == Trunk[index].trunk_state ) { Trunk[index].trunk_state = TRUNK_BUSY; ... // program code }
表达式和基本语句
5、长语句要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行 长语句要在低优先级操作符处划分新行, 长语句要在低优先级操作符处划分新行 操作符放在新行之首, 要进行适当的缩进。使排版整齐,语句可读。 要进行适当的缩进。使排版整齐,语句可读。 [示例] 常用的写法: if ((taskno < max_act_task_number) && (n7stat_stat_item_valid (stat_item))) { ... // program code } 正确的写法: if ((taskno < max_act_task_number) && (n7stat_stat_item_valid (stat_item))) { ... // program code }
表达式和基本语句
2、switch语句必须有 语句必须有default分支。 分支。 语句必须有 分支 3、写代码时,要注意表达式是否会上溢、下溢。 写代码时, 写代码时 要注意表达式是否会上溢、下溢。 [示例]:如下程序将造成变量下溢。 unsigned char size ; while (size-- >= 0) // 将出现下溢 { ... // program code } 当size等于0时,再减1不会小于0,而是0xFF,故程序是一个死循环。应如下修改。 char size; // 从unsigned char 改为char while (size-- >= 0) { ... // program code } 在以后的工作中,这个错误是经常会碰到的,特别是在修改别人的代码时,一不注 意就有可能出现这种错误,这个错误很难查,有时这个问题会卡你很久。
排版规则
看了以上几段代码,有没有和你们自己的习惯相同的?如果有的话以后就需要改正 了。下面是正确的代码和规范: if (NULL == pUserCR) { return; } for (...) { ... // program code } if (...) { ... // program code } void example_fun( void ) { ... // program code }
注释错误
注释的错误有很多,最常犯的有3种: 1. 在函数头和源文件头要有注释 在函数头和源文件头要有注释; 2. 注释与所描述内容进行同样的缩进 注释与所描述内容进行同样的缩进; 3. 修改代码同时更新相应的注释,保证注释与代码的一致性。不再有用的注释要删 修改代码同时更新相应的注释,保证注释与代码的一致性。 除。 [示例]:如下例子,排版不整齐,阅读稍感不方便。 void example_fun( void ) { /* code one comments */ CodeBlock One } 应改为如下布局。 void example_fun( void ) { /* code one comments */ CodeBlock One }
排版规则
除了{}相关的错误外,还有两种错误比较常见,一种是把多个短语句写在一行中; 把多个短语句写在一行中; 把多个短语句写在一行中 一种是空格的相关问题 空格的相关问题。 一种是空格的相关问题。 [示例]:如下例子不符合规范。 rect.length = 0; rect.width = 0; Int data = 0, ret = 0; 应如下书写 rect.length = 0; rect.width = 0; Int data = 0; Int ret = 0; 大家可能能会觉得变量定义的时候分两行写比较繁琐,但是这是有原因的。首先, 这样写比较清楚,方便查找哪些是调试用的变量,在正式的代码版本中去除;其 次,方便给每个变量写注释。
变量、结构
B、 UINT32 getAlarmInStatus(void) { return currExceptionStatus[ALARMIN_EXCEPTION]; } C、 pDevCfgParam->heartbeatCfg.bEnableHeartbeat = (FALSE == ntohl (netRetManageCfg.enable)) ? FALSE : TRUE) 4、结构体中的数据应注意字节对齐,不足的用res补足。 结构体中的数据应注意字节对齐,不足的用 补足 补足。 结构体中的数据应注意字节对齐 typedef struct { UINT16 bAllDayRecord; /* 是否全天录像 */ UINT8 recType; /* 录象类型 */ UINT8 res; }RECORDDAY;