写数组时的内存格式是什么,其中数组的名称是指针,其中的机制是什么? C/C++

问题描述 投票:0回答:2

!!问题有点长,所以我分成了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中的内存真的像图中那样一分为二吗?指针的哪一半和矩阵的一半,如果是这样,机制是什么?

示意图: The picture shows the divisions of the ram in the form of a list of boxes, and the picture shows how this drawing concluded that through the arrows directed on each section, and it expresses an already written output process.

c++ arrays algorithm pointers data-structures
2个回答
0
投票

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 个橙子不是 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...(恕我直言)。

© www.soinside.com 2019 - 2024. All rights reserved.