C语言陷阱与缺陷详解

需积分: 45 9 下载量 54 浏览量 更新于2024-08-04 收藏 462KB PDF 举报
"C陷阱与缺陷读书笔记整理" 这篇读书笔记主要涵盖了C语言中常见的陷阱和缺陷,通过细致的分类和实例解析,帮助读者理解和避免这些潜在的问题。笔记内容包括词法陷阱、语法陷阱、语义陷阱、连接过程、库函数的使用、预处理器的注意事项以及可移植性缺陷,并给出了相应的解决建议。 一、词法陷阱 1. =不同于== 混淆赋值运算符(=)和相等比较运算符(==)可能导致逻辑错误,应当养成良好的编程习惯,如使用if (NULL == p->s)来避免误用。 2. &和|不同于&&和|| 按位运算符(& 和 |)与逻辑运算符(&& 和 ||)有明显的区别,逻辑运算符会考虑短路效应,而按位运算符不考虑。 3. 单字符符号与多字符符号 单字符符号常量由一个字符组成,而多字符符号常量可能会导致意外的行为,通常不推荐使用。 二、语法陷阱 1. 函数声明 正确理解函数声明的重要性,确保函数原型和实现匹配,避免类型不匹配。 2. 运算符的优先级问题 熟悉运算符优先级,使用括号明确表达式计算顺序。 3. 分号的使用 分号作为语句结束标志,遗漏可能导致语法错误。 4. switch语句 注意case后面的break,防止意外执行其他case分支。 5. 函数调用 确保参数传递正确,避免类型不匹配和内存泄漏。 6. 悬挂else问题 else总是与最近未配对的if匹配,避免结构混乱。 三、语义陷阱 1. 指针与数组 指针和数组在某些情况下可以互换使用,但它们是不同的数据类型,需谨慎处理。 2. 非数组的指针 指针解引用需确保指向有效内存,避免野指针。 3. 数组声明 数组作为参数时,实际传递的是数组首地址,而非整个数组。 4. 避免“举隅法” 尽量避免隐含类型转换,使用显式类型转换提高代码可读性。 5. 空指针与空字符串 空指针(NULL)与空字符串("\0")是两个概念,不可混用。 6. 边界计算与不对称性 访问数组时注意边界,避免越界。 7. 求值顺序 运算符的求值顺序可能不确定,使用括号明确顺序。 8. 运算符&&、||和! 理解短路效应,合理使用逻辑运算符。 9. 整数溢出 避免整数溢出可能导致的计算错误。 10. 为函数main提供返回值 main函数必须有返回值,尤其是退出程序时。 四、连接 1. 连接器的作用 连接器负责将编译后的目标文件合并为可执行文件。 2. 声明与定义 理解声明与定义的区别,避免重复定义。 3. 命名冲突与static修饰符 使用static修饰符避免全局变量的命名冲突。 4. 形参、实参与返回值 确保函数调用时参数类型和数量匹配,返回值正确处理。 5. 检查外部类型 注意不同源文件间的数据类型一致性。 6. 头文件 正确包含头文件,避免重复定义和依赖问题。 五、库函数 1. 返回整数的getchar函数 理解getchar函数的返回值类型,避免类型不匹配。 2. 更新顺序文件 正确使用文件操作函数,确保数据的完整性和顺序。 3. 缓冲输出与内存分配 了解输出缓冲区的机制,合理管理内存。 4. 使用errno检测错误 学会利用errno全局变量检测函数调用的错误状态。 5. 库函数signal 理解和使用信号处理函数,处理程序异常。 六、预处理器 1. 宏定义中的空格 宏定义中的空格可能影响替换结果,需谨慎处理。 2. 宏不是函数 宏展开是在预处理阶段完成的,没有函数调用的特性。 3. 宏不是语句 宏可以扩展成多行,但不是独立的语句,需注意分号。 4. 宏不是类型定义 宏无法用于类型定义,应使用typedef。 七、可移植性缺陷 1. C语言标准变更 遵循最新的C语言标准,保证代码的跨平台兼容性。 2. 标识符名称限制 了解不同平台对标识符长度和字符集的限制。 3. 整数的大小 不同系统中整数的位宽可能不同,使用类型安全的函数。 4. 字符的有符号无符号 确保字符类型(char)是有符号还是无符号的正确处理。 5. 移位运算符 了解不同平台的移位运算规则,避免溢出和负数移位问题。 6. 内存位置为0 有些平台不支持地址为0的内存访问,避免硬编码。 7. 除法运算截断 浮点除法可能产生截断误差,整数除法要注意向下或向上取整。 8. 随机数大小 了解平台的随机数生成范围,避免溢出。 9. 大小写转换 大小写转换函数可能依赖于系统配置。 10. 释放后再分配 释放内存后立即重新分配可能导致问题,建议使用NULL初始化。 八、建议 1. 不要相信错误 对潜在错误保持警惕,编写健壮的代码。 2. 直接表达意图 代码应清晰表达其目的,避免模糊的表达方式。 3. 考察简单特例 通过测试最简单的情况来发现和修复问题。 4. 使用不对称边界 在边界条件上使用明确的边界,避免歧义。 5. 注意潜伏的bug 对可能的错误保持敏感,进行详尽的测试。 6. 防御性编程 假设错误会发生,提前采取预防措施。 这些笔记提供了C语言编程中需要注意的关键点,有助于提高代码质量和可维护性。通过学习和实践,开发者可以更好地避免陷阱,提升编程技能。