数组名称和数组名称的地址如何打印相同的值?

How can array name and the address of the array name both prints the same value?

考虑以下代码片段。

int main(){
    int x[2];
    x[0]=100;
    x[1]=200;
    printf("%d\n",x);
    printf("%d\n",&x);
    printf("%d\n",*x);
}   

输出为(三行)

6487616  6487616 100

我读到数组名称是指向数组第一个元素的指针。因此,'x' 的值打印了一个内存地址。但是如果我尝试打印保存数组第一个元素地址的指针的地址,为什么它也打印相同的内存地址?它不应该打印另一个内存地址,仅仅是因为为了让变量存储内存地址,它应该是一个指针,并且该指针变量在 RAM 中也有一个内存地址。

int main(){
   int y = 10;
   int *p = &y;

   printf("%d\n",&y);
   printf("%d\n",&p);   
}

以上代码给出的输出为

6487628 6487616

那么为什么这对数组不起作用?

与您可能听到的相反,数组和指针不是一回事。数组是给定类型的一个或多个元素的序列,而指针指向内存位置(可能是数组的第一个元素)。因此,数组的地址与第一个元素的地址相同。

令人困惑的是,在大多数表达式中,数组 衰减 为指向第一个元素的指针。这种衰减不会发生的情况之一是当数组是 address-of 运算符 &.

的主题时

在您的第一段代码中,您首先打印 x。暂时忽略您应该使用 %p 来打印指针而不是 %d,此处 x 衰减为指向第一个元素的指针,并且该地址就是打印的内容。在对 printf 的下一次调用中,您传入 &x。这与 x 具有相同的值(当转换为指针时)但具有不同的类型,即 x 具有类型 int [2](衰减为 int *)和 &x 的类型为 int (*)[2].

在您的第二个示例中,yintpint *。这些是单独的变量,因此每个都有不同的地址。

你听到的有点不对。

数组不是 "a constant pointer"。数组就是数组。

当您在表达式中使用数组时,您得到的是指向数组第一个元素的指针。

该指针将与指向整个数组的指针具有相同的值(尽管类型不同)。

这些事实解释了您看到的结果。

你应该使用 %p 打印内存地址

#include <stdio.h>

int main(){
   int y = 10;
   int *p = &y;

   printf("%p\n",&y);
   printf("%p\n",&p);
}

输出:

0x7ffeed2dd6fc

0x7ffeed2dd6f0

顺便说一句

int main(){
    int x[2];
    x[0]=100;
    x[1]=200;
    printf("%p\n",x); // u should use %p here
    printf("%p\n",&x); // this is the address of the array same as upper
    printf("%d\n",*x); // this is the value of x it's same as x[0]
} 

首先,对于打印内存地址,应该使用%p而不是%d;使用 %d 实际上是未定义的行为,即使它经常有效:

int main(){
    int x[2];
    x[0]=100;
    x[1]=200;
    printf("%p\n",(void*)x);
    printf("%p\n",(void*)&x);
    printf("%d\n",*x);
}

其次,&x没有引入新的对象/变量而是使用对象x的地址。 x 的使用衰减到指向数组对象 x 的第一个元素的指针,这等同于 &x&x[0]。所以相同的对象 -> 相同的地址,因此,x&x&x[0] 给你相同的地址。

在另一个示例中,您引入了一个新对象 p,它不同于对象 x。这就是为什么 &p&x 给出不同的地址