关于C语言printf内变量赋值、增量运算结果不符的技术疑问
关于C语言逻辑运算符短路求值的疑问
问题1
i = 7; j = 8; k = 9; printf("%d ",(i = j) || (j = k)); printf("%d %d %d\n", i, j, k);
- 预期输出:
1 9 9 9 - 实际输出:
1 8 8 9
疑问:为何第一个printf中的赋值操作后,i和j的值未如预期改变?原以为括号内的赋值表达式(i = j)和(j = k)会从右到左优先执行,i、j应变为9,但实际输出为8、8。
解答:这是因为C语言中逻辑或运算符||具有短路求值特性:如果左侧表达式的结果为真(非0),右侧表达式会直接被跳过,不会执行。
这里(i = j)执行后,i被赋值为8(非0,属于真),所以右侧的(j = k)根本不会运行,j的值自然还是原来的8,k也保持9不变。
另外,你混淆了运算符优先级和求值顺序:赋值运算符是右结合,但逻辑或的优先级低于赋值,不过这里短路求值才是核心原因,和从右到左执行无关——逻辑或的求值顺序是从左到右,不是从右到左。
问题2
i = 1; j = 1; k = 1; printf("%d ", ++i || ++j && ++k); printf("%d %d %d\n", i, j, k);
- 预期输出:
1 2 2 2 - 实际输出:
1 2 1 1
疑问:为何第一个printf中的前缀增量操作后,j和k的值未改变?原以为前缀增量优先级更高,i、j、k都会变为2,但实际j、k仍为1。
解答:首先,逻辑与&&的优先级确实高于逻辑或||,所以表达式会被解析为++i || (++j && ++k)。但同样因为短路求值:左侧的++i执行后,i变成2(非0,真),整个逻辑或表达式的结果已经确定为真,所以右侧的(++j && ++k)完全不会执行,j和k自然保持初始值1。
优先级只决定表达式的分组方式,不决定求值顺序——逻辑运算符的求值顺序都是从左到右,一旦能确定整个表达式的结果,后续部分就不会运行。
内容的提问来源于stack exchange,提问作者ChicoTabi
相关产品推荐
相关产品推荐

