必看!15个C语言常见陷阱及避坑指南

电子说

1.3w人已加入

描述

 

C语言虽强大,但隐藏的“坑”也不少!稍不留神就会导致程序崩溃、数据异常。本文整理15个高频陷阱,助你写出更稳健的代码!  

陷阱1:运算符优先级混淆 

问题:运算符优先级不同可能导致计算顺序错误。  

int a = 5, b = 3;  

int c = a++ * --b;  // a=6, b=2, c=10  

若写成 ++a * b--,结果会变为 c=18(a=6, b=2)。  

解决:  

熟记优先级表,或用括号明确顺序:  

int c = (a++) * (--b);  

陷阱2:变量名大小写敏感

问题:myVar和 MyVar会被视为不同变量。  

int MyVar = 5;  

int myvar = 3;  

printf("%d", MyVar + myvar);  // 输出8  

解决:  

统一命名风格(如全小写+下划线),避免混淆。

陷阱3:数组越界访问

问题:访问不存在的下标导致崩溃或数据污染。  

int arr[3] = {1,2,3};  

int x = arr[3];  // 越界!  

解决:  

牢记数组下标范围是 0到长度-1。

陷阱4:整型溢出

问题:数值超出类型范围会“循环”取值。  

unsigned char x = 255;  

x += 1;  // x=0  

解决:  

预估数值范围,选用 `int32_t`、`uint64_t` 等合适类型。

陷阱5:空指针解引用

问题:未初始化指针直接使用导致崩溃。  

int *p = NULL;  

*p = 5;  // 致命错误!  

解决:  

使用前检查指针有效性:  

if (p != NULL) *p = 5;  

陷阱6:随机数种子未设置

问题:rand()默认种子固定,导致随机序列重复。  

for (int i=0; i<10; i++) {  

    printf("%d ", rand());  // 每次输出相同序列  

}  

解决:  

用 srand(time(NULL))`初始化种子。

陷阱7:字符串未正确终止  

问题:忘记添加 `` 导致字符串异常。  

char str[10] = "hello";  

str[5] = 'w';  // 覆盖了原结尾的  

printf("%s", str);  // 输出乱码  

解决:  

手动补 ``:  

str[5] = 'w';  

str[6] = '';  

陷阱8:死循环 

问题:循环条件错误导致无限执行。  

int i=0;  

while (i < 10) {  

    printf("%d ", i);  

}  // i未自增,死循环!  

解决:  

检查循环变量是否更新,或用 `for` 替代。

陷阱9:变量作用域错误

问题:在作用域外访问变量。  

if (x == 1) {  

    int y = 2;  

}  

printf("%d", y);  // 编译错误!  

解决:  

理解作用域规则,必要时将变量声明在外部。

陷阱10:隐式类型转换

问题:未显式转换导致结果错误。  

int a = 5;  

double b = 2.0;  

printf("%f", a / b);  // 正确写法:(double)a / b  

解决:  

手动强制转换类型,避免隐式转换歧义。

陷阱11:函数参数不匹配  

问题:参数数量或类型错误导致编译失败。  

int add(int a, int b);  

printf("%d", add(1,2,3));  // 参数过多!  

解决:  

严格匹配函数声明与调用参数。

---

陷阱12:空结构体指针访问

问题:未初始化指针访问成员导致崩溃。  

struct Person *p = NULL;  

printf("%s", p->name);  // 访问空指针!  

解决:  

检查指针是否有效后再操作。

陷阱13:文件未正确关闭

问题:未处理 `fopen` 失败或忘记 `fclose`。  

FILE *fp = fopen("test.txt", "r");  

// 未检查fp是否为NULL  

fclose(fp);  // 若fp为NULL,程序崩溃  

解决:  

始终检查文件指针,并确保关闭:  

if (fp != NULL) fclose(fp);  

陷阱14:宏定义未加括号

问题:宏展开后运算顺序错误。  

#define SQUARE(x) x*x  

int b = SQUARE(a+1);  // 展开为a+1*a+1=2a+1  

解决:  

宏参数用括号包裹:  

#define SQUARE(x) (x)*(x)  

陷阱15:多线程未同步 

问题:多线程竞争导致数据错乱。  

// 两个线程同时调用printf可能输出乱序  

pthread_create(&t1, NULL, print_msg, "Thread1");  

pthread_create(&t2, NULL, print_msg, "Thread2");  

解决:  

使用互斥锁(mutex)或信号量同步线程。

总结:C语言陷阱虽多,但通过规范编码、充分测试和工具检查(如静态分析工具),可大幅降低风险。建议收藏本文,编码时多自查!  

审核编辑 黄宇

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 相关推荐
  • C

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分