如果您尝试这段代码
#include<stdio.h> int main() {
// Pointer to an integer
int *p;
// Pointer to an array of 5 integers
int (*ptr)[5];
int arr[] = { 3, 5, 6, 7, 9 };
// Points to 0th element of the arr.
// Points to the whole array arr.
ptr = &arr;
printf("p = %p, address of P = %p\n", p, &p);
return 0; }
您将得到类似p = 0x7fff8e9b4370, P address = 0x7fff8e9b4340
的信息
这意味着指针P的地址是某些东西,而其中的数据是另一个
但是如果您使用这样的数组指针尝试相同的操作
#include<stdio.h> int main() {
// Pointer to an integer
int *p;
// Pointer to an array of 5 integers
int (*ptr)[5];
int arr[] = { 3, 5, 6, 7, 9 };
// Points to 0th element of the arr.
p = arr;
// Points to the whole array arr.
ptr = &arr;
printf("arr = %p, arr address = %p\n", arr, &arr);
return 0; }
您将获得类似arr = 0x7ffda0a04310, arr address = 0x7ffda0a04310
那为什么指针数据与内存中的指针地址相同呢?当我们取消引用arr指针的地址时,我们应该获得数字3,但是据我了解,这是内存中的地址位置0x7ffda0a04310
以0x7ffda0a04310
作为数据
那么我在哪里弄错了?
答案 0 :(得分:2)
打印p
表示打印p
的值,而p
的值是整数的地址或整数数组的地址。
打印&p
表示您在内存中打印p
的位置。
打印arr
将显示数组的第一个元素的地址,即&arr[0]
。
打印&arr
将显示arr在内存中的位置,它也是数组第一个元素的地址
因此,打印p
与打印&p
会有所不同。
arr
和&arr
是不同的类型,但是会得到相同的结果。
答案 1 :(得分:1)
这是因为当您使用数组的符号时,它实际上的计算结果为2018-10-09 21:08:02.019 12545-12545/com.omg_indo.itmsapp D/tag: com.android.volley.ParseError: org.json.JSONException: Unterminated object at character 30 of {"error":"Email doesn't exist"
(第一个元素的地址)。因此,因此&arr
和arr
是相同的地址(但类型不一样!)。
&arr
的类型为arr
int*
的类型为&arr
区别在于执行指针算术的时间。递增int(*)[5]
将到达下一个元素的地址。因此,arr
与*(arr+1)
基本相同。
递增arr[1]
会跳过整个数组(递增指针总是会跳过类型的整个大小)
答案 2 :(得分:1)
您发现的是数组的地址与其第一个成员的地址相同。
在表达式中使用数组arr
时,在大多数情况下,它会衰减为指向其第一个元素的指针。因此,表达式中的arr
等效于&arr[0]
。由于arr
的成员具有类型int
,因此表达式&arr[0]
(并且扩展名为arr
)具有类型int *
。
在某些情况下,这种衰减不会发生。其中之一是当数组是&
运算符的操作数时。因此,表达式&arr
的类型为int (*)[5]
,即指向大小为5的int
数组的指针。
关于为什么这两个地址的值相同的原因,如果您看一下,这是有道理的:
arr
-------
0x7ffda0a04310 | 0 |
-------
| 0 |
-------
| 0 |
-------
| 0 |
-------
0x7ffda0a04314 | 1 |
-------
| 1 |
-------
| 1 |
-------
| 1 |
-------
...
看看这一点,您可以看到数组本身和数组的第一个元素从同一地址开始。
因此arr
(作为表达式)的类型为int *
,而&arr
的类型为int(*)[5]
,但是两者的值相同。