被`i = i++ + ++i;`整哭的人,举手!

这句看着像绕口令的玩意儿,在C语言群里炸过无数次锅:新手写完一运行,发现结果和想象差了十万八千里whatsapp网页版,评论区顿时变成比惨大会。

别急着骂人,今天把它拆成碎片一次性讲清,看完以后再碰到优先级和“副作用”这两个幽灵,至少知道先把锅甩给谁。

先贴一个真事故现场:

```c
int i = 1;
int j = i++ + ++i; // 猜猜j==?
```
有人猜3,有人猜4whatsapp登录,甚至有狠人猜到5。编译器给的答案却是3——别哭,这不是bug,是你误踩了“序列点”地雷。
C语言里,同一个变量在一次表达式里被多次修改且中间没有序列点(&&、||、?:、逗号、函数调用这些才算),结果属于“未定义行为”。
标准都懒得回答3还是4,直接甩锅给编译器自由发挥。
简单说:这不是考数学,而是考规矩没背熟。
再换个安全点的版本:
```c
int a = 5;
int b = a++ 3; // 结果b=15,a随后变6
```
这时候就稳稳当当,副作用在分号那一刻才生效。
再来说说赋值里的“作弊器”复合运算符。
见过写嵌入式的大佬把ADC滤波写成这样:
```c
avg += (new - avg) >> 2; // 等价于 avg = avg + ((new -avg)/4),省掉一次除法
```
一行代码既躲过了浮点,又让芯片少跑几百个时钟,顺手把滤波做好,老司机的“懒人”操作简直艺术。
至于关系逻辑那块,面试常考的一题:下面两段哪个打印“OK”?
```c
// A
if (a = 0) printf("OK");
// B
if (a == 0) printf("OK");
```
一眼看错的人当年连挂三轮。
`=`是赋值,`==`才是判等,写错编译器都不报错,因为语法上没错——它只当你想把0写进a然后问“结果是不是0?”这种哑巴吃黄连的错误,lint工具都笑而不语。
有人问了:运算符优先级背不下来咋办?
一个土办法:把“单算关逻赋”五个字抄桌子角——单目 > 算术 > 关系> 逻辑 > 赋值,口诀一念,谁还抄那一大张表。
真遇到记不住的时候,括号才是永远的神。
别死扛脑容量,偷懒不丢人。
最后再补一个冷知识:
逗号表达式经常被误会成只是“分隔符”,实际人家是正经表达式,优先级最低,值取最后一坨。
```c
int x = (1, 2, 3); // x==3,前面两个“1、2”纯粹跑龙套
```
写宏的时候用这招能在同一代码行多干几件事,不过可读性直接坠崖,除了炫技基本没人买账。
总结一句话:C的这些符号,看起来冷冰冰,其实就是一堆“规矩+地雷”。
规矩背熟,地雷能跳则跳,实在要踩,至少知道炸完怎么补锅。
下次再被`++--==`晃瞎眼,先默念口诀、加括号,实在不信邪,拆成三行写。
代码跑通了whatsapp网页版,再发朋友圈嘚瑟也来得及。
