请原谅业余爱好者,但我真的很难理解基本的增量机制。评论是否正确?
#include <stdio.h>
main()
{
int a[5]={1,2,3,4,5};
int i,j,m;
i = ++a[1]; // the value of a[1] is 3. i=3
j = ++a[1]; /* because of the previous line a[1]=3
and now a[1]=4? but not in the line defining i? */
m = a[i++]; /* i retained the value of 3 even though the value of a[1] has changed
so finally i++ which is incremented in printf()? */
printf("%d, %d, %d", i,j,m);
}
我可以回答我自己的问题,但到目前为止,我已经骗了很多次学习C.
答案 0 :(得分:3)
i = ++a[1]
会将a[1]
的值增加到3
,而++a[1]
的结果3
将被分配给i
。
j = ++a[1];
会将a[1]
的值增加到4
,而++a[1]
的结果4
将被分配给j
。
m = a[i++];
,会将a[3]
的值(因为i
现在为3 b)分配给m
4
和i
将增加1
。现在i
变为4
。
答案 1 :(得分:3)
使用++
和--
运算符要记住的是表达式具有结果和副作用。 ++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 |
+---+