与++和--运营商记住的是,表达具有结果和副作用。 结果的++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 |
+---+