请记住,在大多数表达式中,数组名称很容易衰减为指向第一个元素的指针(阅读一些异常,其中数组名称没有衰减为指向第一个元素的指针? @ H 2 CO 3巧妙地回答了)。
为了更好地理解,请考虑我的图表:
首先,假设a
存储在内存中如下。
a
+----+----+----+----+---+
| 0 | 1 | 2 | 3 | 4 |
+----+----+----+----+---+
▲ ▲ ▲ ▲ ▲
| | | | |
a a+1 a+2 a+3 a+3
声明static int *p[] = {a, a+1, a+2, a+3, a+4};
创建了一个指向整数的新指针数组,具有以下值:
p[0] == a
p[1] == a + 1
p[2] == a + 2
p[3] == a + 3
p[4] == a + 4
现在,p
也可以假设存储在内存中,如下所示:
p
+----+----+----+----+-----+
| a |a +1| a+2| a+3| a+4 |
+----+----+----+----+-----+
▲ ▲ ▲ ▲ ▲
| | | | |
p p+1 p+2 p+3 p+4
分配后ptr = p;
的事情将是这样的:
p a
+----+----+----+----+-----+ +----+----+----+----+---+
| a |a +1| a+2| a+3| a+4 | | 0 | 1 | 2 | 3 | 4 |
+----+----+----+----+-----+ +----+----+----+----+---+
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
| | | | | | | | | |
p p+1 p+2 p+3 p+4 a a+1 a+2 a+3 a+3
ptr
Notice: ptr points to first location in pointer array p[]
表达式:**ptr++;
现在我们考虑**ptr++;
第一个 printf 语句之前的表达式。
ptr
等于是 p
指针数组中第一个元素的地址。因此,ptr
指向p[0]
数组中的第一个元素(或者我们可以说ptr
== &p[0]
)。
*ptr
意味着p[0]
并且因为p[0]
是 a
,所以 *ptr
是a
(所以*ptr
== a
)。
并且因为*ptr
is a
, then **ptr
is *a
== *(a + 0)
== a[0]
那就是0
.
请注意,在表达式中**ptr++;
,我们不会将其值分配给任何 lhs 变量。
所以 of 的效果就和== =**ptr++;
一样,
就是在这个表达式指向之后(或者我们可以说== )。ptr++;
ptr = ptr + 1
p + 1
ptr
p[1]
ptr
&p[1]
打印一:
在第一次 printf 事情变成:
p a
+----+----+----+----+-----+ +----+----+----+----+---+
| a | a+1| a+2| a+3| a+4 | | 0 | 1 | 2 | 3 | 4 |
+----+----+----+----+-----+ +----+----+----+----+---+
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
| | | | | | | | | |
p p+1 p+2 p+3 p+4 a a+1 a+2 a+3 a+3
ptr
Notice: ptr is equals to p + 1 that means it points to p[1]
现在我们可以理解First printf:
ptr - p
输出1
因为:
ptr = p + 1
, 所以ptr - p
== p + 1 - p
==1
*ptr - a
输出1
因为:
ptr = p + 1
, 所以*ptr
== *(p + 1)
== p[1]
==a + 1
这意味着:*ptr - a
= a + 1 - a
==1
**ptr
输出1
因为:
*ptr
==a + 1
从第 2 点开始
所以**ptr
== *(a + 1)
== a[1]
==1
表达式:**++*ptr;
在第一个 printf 之后,我们有一个表达式 *++*ptr;
。
正如我们从上面第 2 点知道的那样*ptr
== p[1]
。因此,++*ptr
(即++p[1]
)将p[1]
增加到a + 2
再次理解,在表达式中*++*ptr;
我们没有将它的值赋给任何 lhs 变量,所以效果 *++*ptr;
就是++*ptr;
.
现在,在第二个 printf 事情变成:
p a
+----+----+----+----+-----+ +----+----+----+----+---+
| a |a+2 | a+2| a+3| a+4 | | 0 | 1 | 2 | 3 | 4 |
+----+----+----+----+-----+ +----+----+----+----+---+
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
| | | | | | | | | |
p p+1 p+2 p+3 p+4 a a+1 a+2 a+3 a+3
ptr
Notice: p[1] became a + 2
打印-2:
现在我们可以理解第二个printf 了:
ptr - p
输出1
因为:
ptr = p + 1
, 所以ptr - p
== p + 1 - p
==1
*ptr - a
输出2
因为:
ptr = p + 1
so *ptr
== *(p + 1)
== p[1]
==a + 2
这意味着:*ptr - a
== a + 2 - a
==2
**ptr
输出2
因为:
*ptr
==a + 2
从第 2 点开始
所以**ptr
== *(a + 2)
== a[2]
==2
表达式:++**ptr;
现在++**ptr;
在第三个 printf 之前表达。
正如我们从上面第 3 点知道的那样**ptr
== a[2]
。所以++**ptr
==++a[2]
将a[2]
增加到3
所以在第三个 printf 事情变成:
p a
+----+----+----+----+-----+ +----+----+----+----+---+
| a | a+2| a+2| a+3| a+4 | | 0 | 1 | 3 | 3 | 4 |
+----+----+----+----+-----+ +----+----+----+----+---+
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
| | | | | | | | | |
p p+1 p+2 p+3 p+4 a a+1 a+2 a+3 a+3
ptr
Notice: a[2] = 3
打印 3:
现在我们可以理解第三个printf 了:
ptr - p
输出1
因为:
ptr = p + 1
所以ptr - p
== p + 1 - p
==1
*ptr - a
输出2
因为:
ptr = p + 1
so *ptr
== *(p + 1)
== p[1]
==a + 2
这意味着:*ptr - a
= a + 2 - a
==2
**ptr
输出3
因为:
*ptr
==a + 2
从第 2 点开始
所以**ptr
== *(a + 2)
== a[2]
==3
编辑注意:两个指针的区别是 type ptrdiff_t
,为此,正确的转换说明符是%td
, not %d
。
补充一点:
我想补充一下,因为我相信这对新学习者会有帮助
假设我们之前在您的代码中有以下两行,其中还有一个 4 th printfreturn 0;
**++ptr; // additional
printf("%d %d %d\n", ptr-p, *ptr-a, **ptr); // fourth printf
可以检查此工作代码@Codepade,此行输出2 2 3
。
表达式:**++ptr;
因为ptr
等于p + 1
,所以在自增++
操作之后ptr
就变成了p + 2
(或者我们可以说ptr
== &p[2]
)。
在双重尊重操作之后**
==> **(p + 2)
== *p[2]
== *(a + 2)
== a[2]
== 3
。
现在,再次因为我们在这个语句中没有任何赋值操作,所以表达式**++ptr;
的效果只是++ptr;
.
所以表达式后的东西**++ptr;
变成了下图:
p a
+----+----+----+----+-----+ +----+----+----+----+---+
| a | a+2| a+2| a+3| a+4 | | 0 | 1 | 3 | 3 | 4 |
+----+----+----+----+-----+ +----+----+----+----+---+
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
| | | | | | | | | |
p p+1 p+2 p+3 p+4 a a+1 a+2 a+3 a+3
ptr
Notice: ptr is equals to p + 2 that means it points to p[2]
打印 4:
考虑到我在问题中添加的Forth printf:
ptr - p
输出2
因为:
ptr = p + 2
所以ptr - p
== p + 2 - p
==2
*ptr - a
输出2
因为:
ptr = p + 2
so *ptr
== *(p + 2)
== p[2]
==a + 2
这意味着:*ptr - a
= a + 2 - a
==2
**ptr
输出3
因为:
*ptr
==a + 2
从上面第 2 点开始
所以**ptr
== *(a + 2)
== a[2]
==3