C语言编程中的常见错误与陷阱解析

需积分: 0 2 下载量 32 浏览量 更新于2024-07-31 收藏 149KB DOC 举报
"C语言缺陷与陷阱的学习笔记" 这篇文章是一篇关于C语言中常见问题和陷阱的详细总结,适合已经有一定C语言基础的读者深入学习。作者指出,即使自认为已经掌握了C语言,仍然有很多细节和潜在的问题需要了解,因为C语言的灵活性和直接性也可能成为初学者或不熟悉其特性的程序员的困扰。 1. **词法缺陷**: - `=`与`==`的区别:C语言中的赋值运算符`=`和等于比较运算符`==`在书写时很容易混淆,导致逻辑错误。 - `&`与`&&`,`|`与`||`:按位与`&`和按位或`|`与逻辑与`&&`和逻辑或`||`在使用时需注意其逻辑层次和短路特性。 - 多字符常量:C语言允许定义多字符常量,但这在不同系统中可能会有不同的解释,造成可移植性问题。 - 字符串与字符:字符常量在内存中是以单个字符存储,而字符串是以null结尾的字符数组,两者不能混淆使用。 2. **句法缺陷**: - 声明的理解:C语言中的声明语法复杂,正确理解变量类型和作用域至关重要。 - 运算符优先级:不同的运算符有不同的优先级,不熟悉可能导致计算结果不符合预期。 - 分号的使用:分号在C语言中起到语句结束的作用,漏写或误用可能导致程序逻辑错误。 - switch语句:switch语句的fallthrough特性可能导致意外执行下一个case。 - 函数调用:函数参数的传递和返回值处理要谨慎,特别是指针和引用类型。 - 悬挂else问题:if-else结构中,else总是与最近未配对的if匹配,需要注意括号的使用。 3. **连接缺陷**: - 外部类型检查:链接时,编译器不会检查全局变量的类型一致性,程序员需要自行保证。 4. **语义缺陷**: - 表达式求值顺序:C语言中运算符的求值顺序未定义,可能因依赖于特定顺序而产生错误。 - &&、||和!运算符:短路逻辑运算符可能导致部分表达式未被求值,注意副作用。 - 下标从零开始:数组下标从0开始,错误的下标可能导致访问越界。 - 实参转换:C语言不总是自动转换函数实参类型,需确保匹配。 - 指针与数组:虽然指针和数组在某些方面相似,但它们不是一回事,不能混用。 - 避免提喻法:提喻法(typedef)可能导致类型混淆,应谨慎使用。 - 空指针与空字符串:NULL指针与空字符串("")是两个不同的概念,不能等同。 - 整数溢出:C语言不检查整数溢出,可能导致意想不到的结果。 - 移位运算符:左移和右移的位数和类型可能影响结果,需谨慎使用。 5. **库函数**: - getc()返回整数:getc()函数返回的是整数,而非字符,需要注意类型转换。 - 缓冲输出和内存分配:库函数如printf和malloc的行为可能受缓冲区和内存管理策略影响。 6. **预处理器**: - 宏非函数:宏展开是在预处理阶段完成,没有函数调用的特性。 - 宏非类型定义:宏不能用来定义类型,使用typedef或C99的类型定义符更好。 7. **可移植性缺陷**: - 名字约定、整数大小、字符符号性、右移位行为、除法舍入方式、随机数大小、大小写转换、内存释放与重分配等问题,都可能在不同平台上有所不同,编写跨平台代码时需特别注意。 8. **其他**: - 文章还包含一些未详述的章节,如空闲空间和参考文献,可能包含更多关于C语言陷阱的讨论。 通过这篇笔记,读者可以更深入地理解C语言的细节,避免编程过程中的常见陷阱,提高代码质量和可维护性。