首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  C

求问一个关于数组和指针的问题

  •  
  •   waiaan · 55 天前 · 1538 次点击
    这是一个创建于 55 天前的主题,其中的信息可能已经有所发展或是发生改变。
    void main(void)
    {
      int a[5] = {1, 2, 3, 4, 5};
      printf("%p\n", a);
      printf("%p\n", &a);
    }
    

    为什么打印出来结果会是一样的?

    谢谢。

    19 回复  |  直到 2019-10-16 16:21:57 +08:00
        1
    stebest   55 天前
    第一个是数组第一个元素的指针,第二个是数组的指针,打印出来的结果当然一样
        2
    kljsandjb   55 天前 via iPhone
    c 语言的 legacy
        3
    Rasphino   55 天前
    int *p;

    int (*p)[5];
        4
    waiaan   55 天前
    @stebest
    所以 a 还不算一个变量?
        5
    dawn009   55 天前
    @waiaan #4 第一个有隐式类型转换
        6
    CRVV   55 天前
    a 是一个变量,类型是 int[5]

    数组是一段连续的内存上放了多个元素,很多语言的数组( std::vector )是一个 struct,包含了这段内存的地址,数组的长度容量这些信息。

    但是 C 的数组只是那一段用来放元素的内存,没有其它的东西了,数组的地址,数组本身都是指那一段内存。
        7
    stebest   55 天前
    @waiaan 指针不是变量?
        8
    stebest   55 天前
    @waiaan 值一样,但类型不一样,移动的步长不一样!数组指针移动一个位置的话,就跳过了整个数组,元素指针移动一个位置,就跳一个元素
        10
    opensail   55 天前
    测试结果是 0x7ffd361b7420
    0x7ffd361b7420
        11
    opensail   55 天前
    @opensail
    我得理解 a 是一个指针,指向了数组首元素,第一个输出是指针 a 本身得地址,第二个输出是指针 a 所指向元素得地址,也是数组第一个元素,小白回答,望指教,已收藏问题
        12
    waiaan   55 天前
    @opensail

    @stebest

    我查了一下资料,数组名并不是指针,以前理解错了。
        13
    v2bee   55 天前
    《 C 专家编程》里作者说“数组名是指针”的这一页撕下来...
        14
    misaka19000   55 天前
    反编译一下,看汇编就清楚了
        15
    stebest   55 天前
    @v2bee 确实应该当众处刑
        16
    opensail   55 天前
    @stebest 还是 Primer(没有 plus 这本书好,简直是圣经
        17
    shfanzie   55 天前
    void main(void)
    {
    int a[5] = {1, 2, 3, 4, 5};
    printf("%p\n", a);
    printf("%p\n", &a);
    }

    printf("%p\n", a); 打印 a 的地址,a 的地址就是它本身,指向 int[5]的地址;
    printf("%p\n", &a); 这个地方的&是取址运算符,也就意味着取一个变量的地址并付给指针变量。

    所以以上两句打印的同一个地址。
        18
    raysonx   55 天前   ♥ 3
    好久没答语言相关的问题了。 @stebest 和 9 楼的链接是对的。认同“数组名是指针”的建议把以前看的书撕掉。

    C 语言里数组就是数组,在类型上指针是不一样的。当你定义 int arr[10]; 的时候,arr 的类型就是 int[10],sizeof(arr)的结果等于 sizeof(int) * 10 而不是 sizeof(int*)。

    问题在于,在很多情况下 C 语言的数组可以退化(decay)成指向第一个(也可以说第 0 个)元素的指针,比如以参数形式传给另一个函数的时候,比如 foo(arr),或者向另一个指针赋值的时候,比如 int *p = arr。这种情况下的 arr 等价于&arr[0]。C 语言的这种特性可以视为隐式类型转换或者语法糖。如果这时你用 sizeof 去测试 p 或者 foo 函数的参数,你会得到等同于 sizeof(int*)的值也就是指针的长度( 32 位系统下为 4,64 位系统下为 8 )。

    而 &arr 会返回指向整个数组的指针,类型为 int(*)[10]。因为 C 语言的数组实质就是元素组成的连续内存,所以数组的地址和第一个元素的地址在数值上是相等的,这也是为什么 &arr 在数值上等同于 &arr[0]。但注意它们的类型是不同的。如果你对&arr 进行指针运算,比如 &arr + 1,则计算得到的新地址会指向整个数组之后的下一个字节,而不是指向 arr[1]。
        19
    waiaan   55 天前
    @raysonx
    赞,谢谢!
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4227 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 24ms · UTC 08:43 · PVG 16:43 · LAX 00:43 · JFK 03:43
    ♥ Do have faith in what you're doing.