与++
和--
运营商记住的是,表达具有结果和副作用。 结果的++i
是原始值i
加1
。 副作用的++i
是将1
添加到存储在i
中的值。
所以,如果i
本来是0
,然后在表达
j = ++i
j
得到的0 + 1
的结果(i
加上1
原始值)。作为副作用,1
被添加到当前存储在i
中的值。因此,在评估此表达式后,i
和j
都包含1
。
++
的后缀版本略有不同; 结果的i++
是i
的原始值,但副作用是相同的 - 1
被添加到存储在i
中的值中。所以,如果i
本来是0
,然后
j = i++;
j
得到的i
(0
)原始值,并1
被添加到存储在i
值。在此表达之后,j
是0
和i
是1
。
重要 - 没有指定执行j
的分配和i
的副作用的确切顺序。i
确实不是必须在j
被分配之前更新,反之亦然。因此,++
和--
(包括但不限于i = i++
,i++ * i++
,a[i++] = i
和a[i] = i++
)的某些组合将导致未定义的行为;结果会有所不同,不可预知,具体取决于平台,优化和周边代码。
所以,让我们想象一下你的对象在内存布局像这样:
+---+
a: | 1 | a[0]
+---+
| 2 | a[1]
+---+
| 3 | a[2]
+---+
| 4 | a[3]
+---+
| 5 | a[4]
+---+
i: | ? |
+---+
j: | ? |
+---+
m: | ? |
+---+
首先,我们评估
i = ++a[1];
的结果++a[1]
是a[1]
加1原值 - 在这种情况下,3
。 副作用用于更新a[1]
中的值。该语句后,你的对象,现在是这样的:
+---+
a: | 1 | a[0]
+---+
| 3 | a[1]
+---+
| 3 | a[2]
+---+
| 4 | a[3]
+---+
| 5 | a[4]
+---+
i: | 3 |
+---+
j: | ? |
+---+
m: | ? |
+---+
现在我们执行
j = ++a[1];
同样的协议 - j
得到的a[1]
加1的值,副作用是更新a[1]
。评估后,我们有
+---+
a: | 1 | a[0]
+---+
| 4 | a[1]
+---+
| 3 | a[2]
+---+
| 4 | a[3]
+---+
| 5 | a[4]
+---+
i: | 3 |
+---+
j: | 4 |
+---+
m: | ? |
+---+
最后,我们有
m = a[i++];
的i++
结果是3
,所以m
将储存a[3]
值。副作用是将1
添加到存储在i
中的值。现在,我们的物品看起来像
+---+
a: | 1 | a[0]
+---+
| 4 | a[1]
+---+
| 3 | a[2]
+---+
| 4 | a[3]
+---+
| 5 | a[4]
+---+
i: | 4 |
+---+
j: | 4 |
+---+
m: | 4 |
+---+
这不太清楚问题在这里 - 你观察到了什么行为? –
程序打印4,4,4 我想了解增量是否改变了[1]的实际值,还是只是为了定义i,j和m。 另外我不确定在printf中实现的后增量() –
我认为问题是“注释是否正确” – drescherjm