You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于K&R《C程序设计语言》中复合赋值运算符expr1计算次数的疑问

问题解答

关于expr1是否必须是左值

没错,不管是使用复合赋值(op=)还是普通赋值,expr1都必须是可修改的左值。因为赋值操作的本质是把计算结果存储到可寻址的内存位置,只有左值(比如变量、数组元素、解引用的指针等)能满足这个要求。如果expr1是像a + b这样的右值,不管用哪种赋值方式都会编译报错——你没法把值赋给一个临时计算结果。

关于“expr1仅计算一次”的含义

这句话的核心是处理带副作用的表达式。如果expr1包含会改变程序状态的操作(比如自增++、自减--,或者调用有副作用的函数),复合赋值和普通赋值的行为会完全不同:

  • 用复合赋值expr1 op= expr2时,expr1只会被计算一次:先算出expr1对应的内存位置和当前值,完成运算后再把结果存回这个位置,整个过程中expr1里的副作用只触发一次。
  • 换成普通赋值expr1 = (expr1) op (expr2)时,expr1会被计算两次:一次是在右边取它的值参与运算,另一次是在左边确定赋值的目标位置。如果expr1有副作用,这两次计算会分别触发副作用,导致结果和预期不符。

举个实际的例子:

int arr[5] = {0};
int idx = 0;

// 使用复合赋值
arr[++idx] += 3;
// 这里++idx只执行1次,idx变为1,arr[1] = 0 + 3 = 3

如果换成普通赋值写法:

int arr[5] = {0};
int idx = 0;

arr[++idx] = arr[++idx] + 3;
// 这里++idx执行了2次,idx变为2,arr[2] = 0 + 3 = 3,arr[1]仍然是0

可以看到,两种写法的结果差异完全来自于expr1(这里是arr[++idx])的计算次数不同。

内容的提问来源于stack exchange,提问作者Azi muth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 22:56:29