请考虑以下代码段。
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
那么为什么在数组方面这不起作用呢?
答案 0 :(得分:4)
与您可能听到的相反,数组和指针不是一回事。数组是给定类型的一个或多个元素的序列,而指针指向存储器位置(可以是数组的第一个元素)。因此,数组的地址与第一个元素的地址相同。
混淆的地方在于,在大多数表达式中,数组将衰减成指向第一个元素的指针。这种衰减没有发生的一种情况是当数组是地址运算符&
的主语时。
在第一段代码中,首先打印x
。暂时忽略您应该使用%p
来打印指针而不是%d
,此处x
会衰减成指向第一个元素的指针,并且该地址是打印的。在下一次调用printf
时,您会传入&x
。它具有与x
相同的值(转换为指针时)但具有不同的类型,即x
具有类型int [2]
(衰减到int *
)和{{ 1}}的类型为&x
。
在第二个示例中,int (*)[2]
为y
,int
为p
。这些是单独的变量,因此每个变量都有不同的地址。
答案 1 :(得分: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
提供不同地址的原因
答案 2 :(得分:-1)
你听到的内容有些不正确。
数组不是"常量指针"。数组是一个数组。
在表达式中使用数组时,得到的是指向数组第一个元素的指针。
该指针将具有相同的值(尽管是不同的类型)作为指向整个数组的指针。
这些事实说明了你看到的结果。
答案 3 :(得分:-1)
您应该使用%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]
}