C语言 将一个指针元素分配给数组中的另一个指针元素是什么意思?



我不太明白将一个指针分配给另一个指针是什么意思?这里 **p 是一个指针/二维数组数组,然后将 p[0] 分配给 p[1],它们都指向同一个地址吗?

#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i,j;
int **p = (int **)malloc(2 * sizeof(int *));
p[0] = (int *)malloc(2 * sizeof(int));
p[1] = p[0];
for(i = 0; i < 2; i++)
for(j = 0; j < 2; j++)
p[i][j] = i + j;
printf("%d",p[0][0]);
return 0;
}

我预计输出为 0,但实际上是 1,为什么?

两个指针p[0]p[1]在表达式语句后具有相同的值

p[1] = p[0];

因此,在使用表达式p[1]的地方,可以将其替换为表达式p[0]因为两个表达式具有相同的值,反之亦然。

在此循环中

for(i = 0; i < 2; i++)
for(j = 0; j < 2; j++)
p[i][j] = i + j;

i等于1j等于0时(假设p[1]p[0]相同。所以p[1][0]等价于p[0][0],等于1i + j

事实上这个循环

for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
p[i][j] = i + j;

等效于循环

for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
p[0][j] = i + j;

因此,外部循环的第二次迭代重写存储在p[0][0]中的值,并在第一次迭代后重写p[0][1]

在第二次迭代中,我们有i等于1.因此,对于 [0, 1] 范围内的j,我们有

p[0][0] = i + j (when i == 1 and j == 0 ) = 1

p[0][1] = i + j (when i == 1 and j == 1 ) = 2

我不太明白将一个指针分配给什么意思 另一个指针?这里 **p 是一个指针/2D 数组数组,然后 p[0] 分配给 p[1],它们都指向同一个地址吗?

是的。 但是,从概念上讲,忽略p[0]p[1]值的重要性(值是指针,以及这些值指向什么(可能更有用,而是关注赋值后它们的值相同的事实。 然后,这些值指向相同的事物,因此。

请注意,我有意选择区分存储位置的指示符(例如"p[1]"(和这些位置的内容(它们的值(的措辞。我们经常使用模糊区别的语言,因为以这种方式精确地说话很麻烦,但你必须在脑海中保持这种区别。 从形式上讲,指针不是表达式p[1],甚至不是它指定的存储位置,而是存储在那里的值。 赋值运算符将该值复制到另一个存储位置,因此,如果根据相同的数据类型解释该其他存储位置的内容,则它们与原始存储位置具有相同的含义。

我预计输出为 0,但实际上是 1,为什么?

因为在设置了p[1] = p[0]之后,表达式p[1][0]指定了与p[0][0]相同的对象。 因此,在分配p[1][0] = 1 + 0后,您可以从p[1][0]p[0][0]中读回结果值 (1(。

它们都指向同一个地址吗?

是的。

这是对程序的修改,应该更清楚地说明这一点:

int main(void) {
int i,j;
int **p = (int **)malloc(2 * sizeof(int *));
p[0] = (int *)malloc(2 * sizeof(int));
p[1] = p[0];
for(i = 0; i < 2; i++)
for(j = 0; j < 2; j++)
p[i][j] = i + j;
for(i = 0; i < 2; i++) {
printf("%d (%p)t", i, p[i]);
for(j = 0; j < 2; j++)
printf("%d ", p[i][j]);
printf("n");
}
return 0;
}

在这里,我们打印出指针值p[0]p[1],以及"二维"数组的所有四个单元格 - 除了,是的,实际上只有两个单元格,对两行中的每一行都执行双重任务。 在我的系统上,这会打印出来

0 (0x7f92ca402710)  1 2 
1 (0x7f92ca402710)  1 2 

你可以清楚地看到这两个指针是相同的。

我们可以把它想象成这样,在记忆中,看起来像这样:

+-------+
p: |   *   |
+---|---+
|
v
+-------+           +---+---+
|   *----------+--->| 1 | 2 |
+-------+     /     +---+---+
|   *--------'
+-------+

另一方面,如果您像这样给malloc打电话三次,而不是两次,如下所示:

int **p = (int **)malloc(2 * sizeof(int *));
p[0] = (int *)malloc(2 * sizeof(int));
p[1] = (int *)malloc(2 * sizeof(int));

你会得到一个更像这样的打印输出:

0 (0x7fb747402710)  0 1 
1 (0x7fb747402720)  1 2 

你会在记忆中得到一张这样的图片:

+-------+
p: |   *   |
+---|---+
|
v
+-------+           +---+---+
|   *-------------->| 0 | 1 |
+-------+           +---+---+
|   *--------.
+-------+          +---+---+
'--->| 1 | 2 |
+---+---+

最新更新