【问题标题】:av[1] and av[1][0] Not the same address?av[1] 和 av[1][0] 不是同一个地址?
【发布时间】:2020-08-16 22:11:39
【问题描述】:

怎么了? 看不懂这个问题。。。 我知道数组的第一个元素存储整个数组的地址。但在这种情况下,我无法弄清楚。

#include <stdio.h>

int main(int ac, char **av)
{
    printf("&av[1]= %p\n", &av[1]);
    printf("&av[1][0]= %p\n", &av[1][0]);

    return(0);
}

输入

./a.out "Hello"

输出

&av[1]= 0x7ffee0ffe4f0
&av[1][0]= 0x7ffee0ffe778

【问题讨论】:

  • av[1]&amp;av[1][0] 是相同的。一个数组(av[1] -- 不是真正的数组,只是暂时使用它)被转换为指向其第一个元素的指针(&amp;av[1][0]

标签: c arrays pointers memory-address argv


【解决方案1】:

av 在这里不是二维数组。这是一个指针数组。

而对于二维数组,&amp;av[1][0] 将与&amp;av[1] 具有相同的地址;在一个指针数组中,&amp;av[1][0] 表示取第二个(索引=1)指针,取消引用它,并给我取消引用的指针目标指向的第一个元素的地址(av[1] 的目标也是指针)。

&amp;av[1]是第二个char*的地址,&amp;av[1][0]是第二个char*指向的第一个字符的地址。不同的东西。

【讨论】:

    【解决方案2】:

    av 是一个指针数组,其中该数组的每个元素都指向一个char arraychar * 类型),其中存储了您作为输入传递给程序的每个字符。

    正如您在程序的以下变体中看到的那样,av[0] 存储av[0][0] 的地址(即指向存储在av[0][0] 中的字符串的第一个位置),其中包含字符. 和@ 987654328@存储av[1][0]的地址(即指向av[1][0]中存储的字符串的第一个位置),其中包含字符H

    #include <stdio.h>
    
    int main(int ac, char **av)
    {
    
        printf("&av[0]= %p\n", &av[0]);
        printf("&av[1]= %p\n", &av[1]);
    
        printf("av[0]= %p\n", av[0]);
        printf("av[1]= %p\n", av[1]);
    
        printf("av[0][0]= %c\n", av[0][0]);
        printf("av[0][1]= %c\n", av[0][1]);
    
    
        printf("av[0][0]= %p\n", &av[0][0]);
        printf("av[0][1]= %p\n", &av[0][1]);
    
        printf("av[1][0]= %c\n", av[1][0]);
        printf("av[1][1]= %c\n", av[1][1]);
    
        printf("av[1][0]= %p\n", &av[1][0]);
        printf("av[1][1]= %p\n", &av[1][1]);
    
        return(0);
    }
    

    提供以下输出:

    $ ./a.out "Hello"
    &av[0]= 0x7fff53625cf8
    &av[1]= 0x7fff53625d00
    
    av[0]= 0x7fff53626ee9
    av[1]= 0x7fff53626ef1
    
    av[0][0]= .
    av[0][1]= /
    &av[0][0]= 0x7fff53626ee9
    &av[0][1]= 0x7fff53626eea
    
    av[1][0]= H
    av[1][1]= e
    &av[1][0]= 0x7fff53626ef1
    &av[1][1]= 0x7fff53626ef2
    

    从图形上看,它类似于(为简化起见,删除了大部分地址):

          av: | 26ee9 | 26ef1 |
                  |       |
                av[0]   av[1] 
     address:   25cf8   25d00
    

       av[0]: |   .  |    /   | ...
                  |       |
              av[0][0] av[0][1] 
     address:   26ee9   26eea
    

       av[1]: |   H  |    e   | ...
                  |       |
              av[1][0] av[1][1] 
     address:   26ef1   26ef2
    

    我希望这能澄清你的疑问。

    【讨论】:

      【解决方案3】:

      如果有人告诉您char **av 声明了一个二维数组,他们对您造成了伤害。在char **av 中,av 是指向char * 的指针,可能是几个char * 中的第一个。所以av[1] 是一个char *——它是一个指向char指针,而&amp;av[1]该指针的地址

      av[1][0]av[1]指向的char&amp;av[1][0]char的地址。

      指向charchar的指针当然不在同一个地方,所以&amp;av[1]&amp;av[1][0]是不同的。

      相比之下,如果您有一个数组,例如char av[3][4],那么av 是一个由3 个数组组成的数组,每组4 个char。在这种情况下,av[1] 是一个由 4 个char 组成的数组,&amp;av[1] 将是该数组的(开始)地址。 &amp;av[1][0] 将是该数组中第一个 char 的地址。由于char在数组的开头,所以数组的地址和char的地址是一样的。

      (但是,它们在 C 实现中不一定以相同的方式表示,使用 %p 打印它们会显示不同的结果,即使它们引用内存中的相同位置。)

      【讨论】:

      • 哇,谢谢你帮了我很多!我最后一个问题可能很愚蠢......你如何区分多维数组和指针数组?
      • @EricLing:类型由标识符的声明决定,除了函数参数的声明自动将数组转换为指针。所以int x[3][4];声明了一个由4个int组成的3个数组,int *x[3];声明了一个由3个指向int的指针组成的数组,int (*x)[4]声明了一个指向4个数组的指针int..在函数参数中, int x[3][4] 声明了一个指向 4 个数组 int 的指针,int *x[3] 声明了一个指向 int 的指针。
      【解决方案4】:

      av 是指向chars 的指针数组的指针。所以它的第二个元素(数组的第二个元素)确实是一个指针。 &amp;av[1] 是它的地址(指针的地址,不是字符的地址)。

      另一方面,av[1][0] 是第二个字符串的第一个字符。它的地址是char 地址,其中存储了第一个字符。

      这两个地址是不同事物的地址,所以它们指向不同的地方是正常的。

      av[1]&amp;av[1][0]分别是指针值(指向第一个字符)和第二个字符串的第一个字符的地址,所以它们必须是显示相同值的指针。 *av[1]av[1][0] 也是如此,它们代表相同的指向字符。

      【讨论】:

        猜你喜欢
        • 2022-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-28
        • 2012-05-10
        相关资源
        最近更新 更多