这最后一批,全是我当年入门半年后踩的坑——结构体、宏定义、位运算、简单的嵌入式开发。很多问题在当时看来毫无头绪,现在回头看只觉得好笑。
前期入门只会踩基础语法坑,真正拉开新手差距的,全是这些课本不讲、编译器不报错、只有实战才会翻车的细节。下面这10条进阶避坑笔记,新手进阶一定要吃透。
1. 结构体内存对齐:字节数总和总对不上
初学算结构体大小,永远和自己预想的不一样。CPU为了读取速度,会自动填充对齐空字节。结构体大小不等于成员简单相加,做协议、做硬件通信经常翻车。
需要精准字节时必须手动关闭对齐:
#pragma pack(1)2. && || 短路机制:条件判断逻辑莫名失效
前面为假,后面代码直接不运行,导致部分函数根本没执行。
if (0 && func()) { // func永远不执行 }3. 位运算和逻辑运算分不清:一个符号之差,全盘报废
&和&&、|和||混用,程序逻辑彻底废掉,肉眼极难发现。
int a = 1, b = 2; if (a & b) // 位与:结果是0,条件为假 if (a && b) // 逻辑与:结果是1,条件为真 // 一个符号之差,整个逻辑全变了4. 有符号/无符号移位规则不同:移位结果总莫名其妙
有符号右移补符号位,无符号右移统一补0,混用之后数值完全错乱。
5. 三目运算符乱拆分:加分号破坏表达式结构
// 错误:乱加分号 int a = (x > y) ? x : y; // 正确:保持完整 int a = (x > y) ? x : y;6. 函数不写返回值类型:现代编译器全报警告
老教材允许隐式int,现代编译器已禁止,必须写全返回值类型。
7. void函数不能return数值
void func() { return; // 正确 return 1; // 错误 }8. const不是绝对安全
以为const变量完全无法修改,实际上指针强转依然能改内存数据,只是编译期保护。
9. 宏定义不加括号:优先级彻底乱套
宏只是纯文本替换,不加括号优先级直接乱套。
#define MUL(a,b) a*b // MUL(1+2, 3+4) 变成 1+2*3+4 = 11,彻底算错 // 正确写法 #define MUL(a,b) ((a)*(b))10. volatile不懂用处:读不到最新硬件数据
初学接触单片机时,不懂volatile。编译器优化缓存变量,永远读不到最新硬件数据,调试到崩溃。
volatile int flag; // 强制每次从内存读取30条初学C语言亲身踩坑笔记,到这篇正式完结了。
我还有一些其他方面的笔记,大家爱看的话,我继续整理:
· 初学汇编踩坑全集
· 初学Socket网络编程踩坑全集
· 初学单片机/嵌入式踩坑全集