我正在独自学习C编程,并坚持这种做法
int a[] = {5,7,9,11,13};
int *p;
int i = 2;
p = a;
*(p++) = ++i;
printf("%d %d %d %d", a[0], a[i++], *p, *(p+2));
// output: 3 11 7 11
我的理解是
1。定义一个数组a
并将其初始化为值5,7,9,11,13
2。定义指针p
3。定义i
并将其初始化为值2
4.p指向数组a
5.p [1] = 3;
//输出:5 11 5 9
但是他们完全错了!
对此我可能需要详细的解释。
请帮助我,非常感谢!
答案 0 :(得分:3)
您的理解是正确的,直到3岁。
4-p
指向a
的第一个元素。
5-您正在使用后递增运算符。因此将使用p
的旧值,并将p
递增(这意味着p
现在将指向a
中的第二个元素)。因此,这等效于p[0] = i + 1; p = p + 1; i = i + 1;
此时,p
指向a
的第二个元素,并且a
的第一个元素被更改为3
。此时的i
也是3
。
a[0] = 3
,a[i++] = a[3] = 11
,*p = a[1] = 7
,*(p+2) = a[3] = 11
。 这正是您获得的输出-请参见here。
答案 1 :(得分:2)
对于*(p++) = ++i;
行
这会将a[0]
的值设置为3。请注意,由于++在p
之后,因此它在表达式之后计算p = p + 1。
a[i++]
是a[3]
,它是11。请注意,计数时从0开始。
我们在p
行增加了*(p++) = ++i;
,因此p
指向a[1]
,即3。
最后*(p+2)
表示p
现在指向11的a[3]
。
您有3 11 7 11
答案 2 :(得分:0)
此
int a[] = {5,7,9,11,13};
p = a;
如下所示
---------------------------------
| 5 | 7 | 9 | 11 | 13 |
---------------------------------
0x100 0x104 0x108 ..(lets assume bas address of a is 0x100)
a
p <-- p pints to base address of a
下次喜欢时
*(p++) = ++i; /* ++i means 3 */
p++
在此表达式中得到相同的(后递增规则)地址,因此3
被分配给0x100
的存储位置,在下一次迭代中p
指向{{ 1}}的内存位置,因此数组0x104
如下所示
a
下一步,当下面的 -----------------------------------------
| 3(5<--old) | 7 | 9 | 11 | 13 |
-----------------------------------------
0x100 0x104 0x108 ..
a |
p <-- p points here
执行如下时
printf()
让我们一个接一个地解决
printf("%d %d %d %d", a[0], a[i++], *p, *(p+2));
然后
*(p+2) == *(0x104 + 2*4)
== 11 (prints 11)
指向*p
的存储位置,7
在p
中产生。
和
0x104
产生a[i++]
,即a[3]
,但对于下一个表达式,11
变成i
。
和
如上图所示, 4
打印a[0]
。因此它打印
3
旁注,未按3 11 7 11.
的定义顺序评估函数参数,请阅读this。
答案 3 :(得分:0)
此行
*(p++) = ++i;
混合使用前增量和后增量。如果您在理解此类代码时遇到困难,则应重写代码,以使每行中仅发生一件事。
在这种情况下,可以将其重写为:
i = i + 1; // From ++i which is the pre-increment, i.e. increment first and
// then use the new value
*p = i; // The assignment without pre/post increments
p = p + 1; // From p++ which is the post-increment, i.e. use the current value and
// then increment afterwards
现在您有3条简单的语句,可以更轻松地理解代码。