你能解释一下输出是 -4
吗?我认为 ++pp;
是 UB 但不确定。您的解释将真正有助于理解。 big-endian 或 little-endian 机器的输出会有什么不同吗?
#include <stdio.h>
int a[] = { -1, -2, -3, -4 };
int b[] = { 0, 1, 2, 3 };
int main(void)
{
int *p[] = { a, b };
int **pp = p;
printf("a=%p, b=%p, p=%p, pp=%p\n", (void*)a, (void*)b, (void*)p, (void*)pp);
++pp;
printf("p=%p, pp=%p *pp=%p\n", (void*)p, (void*)pp, (void*)*pp);
++*pp;
printf("p=%p, pp=%p *pp=%p\n", (void*)p, (void*)pp, (void*)*pp);
++**pp;
printf("%d\n", (++**pp)[a]);
}
我的输出:
a=0x107121040, b=0x107121050, p=0x7ffee8adfad0, pp=0x7ffee8adfad0
p=0x7ffee8adfad0, pp=0x7ffee8adfad8 *pp=0x107121050
p=0x7ffee8adfad0, pp=0x7ffee8adfad8 *pp=0x107121054
-4
最佳答案
当您使用数组名称时(在大多数情况下),它会衰减为指向其第一个元素的指针。这意味着 int* p = a;
和 int* p = &a[0];
完全一样。
因此,要了解在这种情况下会发生什么,只需逐步完成即可。在你的第一点 printf
打电话,事情看起来像这样:
pp p a
+-------+ +------+ +----+----+----+----+
| +---------> +--------> -1 | -2 | -3 | -4 |
+-------+ | | +----+----+----+----+
| |
+------+ b
| | +----+----+----+----+
| +---------> 0 | 1 | 2 | 3 |
| | +----+----+----+----+
+------+
pp
指向 p
的第一个元素, 这是指向 a
的第一个元素的指针.
现在,当您递增 pp
, 它变为指向 p
的第二个元素, 这是指向 b
的第一个元素的指针:
pp p a
+-------+ +------+ +----+----+----+----+
| + | | +--------> -1 | -2 | -3 | -4 |
+---|---+ | | +----+----+----+----+
| | |
| +------+ b
| | | +----+----+----+----+
+---------> +---------> 0 | 1 | 2 | 3 |
| | +----+----+----+----+
+------+
然后您递增 *pp
.自 *pp
是指向 b
的第一个元素的指针,该指针递增以指向 b
的第二个元素:
pp p a
+-------+ +------+ +----+----+----+----+
| + | | +--------> -1 | -2 | -3 | -4 |
+---|---+ | | +----+----+----+----+
| | |
| +------+ b
| | | +----+----+----+----+
+---------> | | 0 | 1 | 2 | 3 |
| + | +----+-^--+----+----+
+---|--+ |
+---------------+
然后你递增**pp
.此时pp
是指向 p
的第二个元素的指针, 所以 *pp
是指向 b
的第二个元素的指针.这意味着 **pp
命名 b
的第二个元素.您从 1
增加它至 2
:
pp p a
+-------+ +------+ +----+----+----+----+
| + | | +--------> -1 | -2 | -3 | -4 |
+---|---+ | | +----+----+----+----+
| | |
| +------+ b
| | | +----+----+----+----+
+---------> | | 0 | 2 | 2 | 3 |
| + | +----+-^--+----+----+
+---|--+ |
+---------------+
现在,让我们剖析 (++**pp)[a]
. ++**pp
和之前一样,所以b
的第二个元素增加到 3
.
现在,对于任何指针 ptr
和整数 n
, ptr[n]
与*(ptr + n)
相同.由于加法是可交换的,ptr + n
与n + ptr
相同.这意味着 ptr[n]
与n[ptr]
相同.
将这些放在一起,这意味着 (++**pp)[a]
与3[a]
相同,与 a[3]
相同. a[3]
是-4
,因此你的结果。
关于c - 双指针输出说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56711010/