在L值中使用后缀增量
可能重复:
后增量算子的评估会以什么顺序发生?
请考虑以下代码段(在C中):
uint8_t index = 10; uint8_t arr[20]; arr[index++] = index;
当我用gcc编译它时,它将arr [10]设置为10,这意味着直到整个赋值表达式之后才应用后缀增量。 我发现这有点令人惊讶,因为我期望增量返回原始值(10)然后增加到11,从而将arr [10]设置为11。
我在RValues中看过很多关于增量运算符的post,但在LValue表达式中没有。
谢谢。
一些标准语言:
6.5表达式
1表达式是一系列运算符和操作数,用于指定值的计算,或指定对象或函数,或生成副作用或执行其组合的操作和操作数。
2在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算修改一次。 72)此外,先前的值应该是只读的,以确定要存储的值。 73)
3语法指示运算符和操作数的分组。 74)除了后面指定的(对于函数调用() , && , || , ?:和逗号运算符),子表达式的评估顺序和副作用发生的顺序都是未指定的。
第2段明确地呈现formsa[i++] = i
undefined的表达式; i
的先前值不只是被读取以确定i++
的结果。 因此,允许任何结果。
除此之外,您不能依赖于在评估表达式后立即应用++
运算符的副作用。 对于像这样的表达式
a[i++] = j++ * ++k
唯一的保证是将表达式j++ * ++k
的结果赋给表达式a[i++]
; 然而,每个子表达式a[i++]
, j++
和++k
可以按任何顺序进行评估 ,并且副作用(分配给a[i]
,更新i
,更新j
和更新k
)可以应用于任何订单。
这条线
arr[index++] = index;
导致未定义的行为。 阅读C标准了解更多详情。
您应该知道的本质是:您不应该在同一语句中读取和更改变量。
赋值操作从右到左工作,即首先计算表达式的右侧部分,然后将其分配给左侧部分。