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

时间:2019-08-09 12:52:21

标签: c loops for-loop pointers assignment-operator

我不太了解将一个指针分配给另一个指针是什么意思?这里** p是一个指针数组/ 2D数组,然后将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,为什么?

3 个答案:

答案 0 :(得分:2)

表达式语句后,两个指针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等于1并且j等于0时(假设p[1]p[0]相同)。因此p[1][0]等于p[0][0],等于i + j的{​​{1}}。

实际上这个循环

1

等同于循环

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

答案 1 :(得分:0)

  

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

是的。但是,从概念上讲,忽略p[0]p[1]的值(这些值是指针,以及这些值指向的内容)的 significance 可能更有用分配后,它们的值相同的事实。然后,这些值指向同一件事。

请注意,我故意选择了措辞,以区分存储位置的指示符(例如“ 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)。

答案 2 :(得分:0)

  

他们两个都指向同一个地址吗?

是的

这是您程序的修改,应该使它更清晰:

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 |
                       +---+---+