!!问题有点长,所以我分成了4个部分,以免读者分心!! 我最近得到一条信息,C/C++ 中数组的名称是指向数组中第一个元素的指针,这是来自 AI(Chat GPT 3.5 和 4)和我在大学的导师。 当我查看每个指针(数组名称)和第一个元素以及存储在指针中的地址的内存位置时,我发现它们都是相等的。
#include<iostream>
using namespace std;
int main (){
int arr[3]{1,2,3};
cout << &(arr) <<" "<<&arr[0] <<" "<< arr <<endl;
return 0;
}
/*
Output:
0x69fee0 0x69fee0 0x69fee0
*/
这里就是第一点或者问题,指针的地址怎么等于指针存储的地址,就好像我们说一个指针指向它自己,这就会变成一个死循环。
搜索这个问题的答案时,发现有专家说矩阵的名字根本不是一个指标。这是第二点.
当我搜索得越来越多时,我找到了一个答案: 确实指针的地址跟它的值是一样的,但这并不意味着指针位于同一个内存空间,他说的是位空间不同,这是由下面的程序推断的:
#include<iostream>
using namespace std;
int main (){
int arr[3]{1,2,3};
cout << &(arr) <<" "<<&arr[0] <<" "<< arr <<endl;
cout << &(arr)+1 <<" "<<&arr[0]+1<<" "<< arr+1<<endl;
cout << &(arr)+2 <<" "<<&arr[0]+2<<" "<< arr+2<<endl;
cout << &(arr)+3 <<" "<<&arr[0]+3<<" "<< arr+3<<endl;
cout << sizeof(arr) <<" "<<sizeof(&arr[0])<<" "<< sizeof(&arr)<<endl;
return 0;
}ٍ
/*
Output:
0x69fee0 0x69fee0 0x69fee0
0x69feec 0x69fee4 0x69fee4
0x69fef8 0x69fee8 0x69fee8
0x69ff04 0x69feec 0x69feec
12 4 4
*/
这是第三点.
关于第四点也是最重要的一点: 就是我通过前面程序的输出推导了内存的形状,就像我们在逻辑电路科学中通过输出推导电路一样。我想让你看看这幅画(不科学,但为了让想法更接近)的总体思路是否正确,对它的任何评论对我来说都非常重要,因为我真的很感兴趣记忆在矩阵的名称是指针的事件。 最后,当你看到图的时候,有一个很重要的问题:RAM中的内存真的像图中那样一分为二吗?指针的哪一半和矩阵的一半,如果是这样,机制是什么?
示意图:
arr
、&arr[0]
和 &arr
将具有相同的值:
arr
打印值是数组的(隐式地址)&arr
打印的值是数组的显式地址。&arr[0]
打印值数组第一个元素的地址,与数组的地址相同但是当索引不同时:
arr
是三个整数的数组。arr + 1
是数组的地址加上sizeof(int)
和&arr[1]
&arr + 1
是数组的地址 + sizeof(arr)
在我们的例子中它等同于 arr+3
,它与 (&arr)[1]
注意类型!
首先,可能有很多表达式具有相同的值,但不是同一类型; 1 个橙子不是 1 个香蕉。
第二,那里没有指针,只有地址。指针是一个变量,您可以在其中存储地址。地址是一个(键入的)值。指针是(类型化的)存储。
arr
是数组(int[3]
类型,即 sizeof(arr)==3*sizeof(int)
),而不是指向数组第一个元素的指针。如果它是一个指针,你就可以写 arr++
,或者 arr = p
(对于其他一些指针 int *p
),这是被禁止的。 arr
是数组,就像 i
是 int i
中的一个整数(i
不是指针吧?)。 typeid(arr).name()
会给出类似 A3_i
(三个整数的数组)的东西。
&arr
是数组的地址。如果你用那个地址做算术,那么它就是sizeof(arr)
。 (&arr)+1
(或&arr+1
)是(整个)数组arr
之后的地址。 typeid(&arr).name()
会给出类似 PA3_i
(指向三个整数数组的指针)的东西。
&(arr[0])
(或&arr[0]
)是arr
的第一个元素的地址,然后是int *
类型的地址。 typeid(&arr[0]).name()
会给出 Pi
(指向 int 的指针)。
现在数组可以在许多上下文中衰减为指针(参数传递、指针赋值、指针算术……)。这意味着
arr
可以被视为它的第一个元素 的地址,即 arr
被视为 &arr[0]
所以是一个 int *
。例如,您可以写 int *p = arr
或 arr+1
。这并不意味着 arr
是一个指针,只是 在这种情况下 arr
被视为其第一个元素的地址。请注意,当您制作cout << arr
时正是这种情况(arr
衰减,因为您看到的是地址而不是数组......)。
注意 array can decay to pointer... 在某种程度上具有误导性,应该说 array decay to address...(恕我直言)。