直到现在,我还认为数组与指针相同。但是我发现了一个奇怪的情况:
int array[5] = { 10,11,12,13,14};
std::cout << array << std::endl;
std::cout << &array << std::endl;
std::cout << &array[0] << std::endl;
int *pArray = new int[5];
std::cout << pArray << std::endl;
std::cout << &pArray << std::endl;
std::cout << &pArray[0] << std::endl;
0x7ffeed730ad0
0x7ffeed730ad0
0x7ffeed730ad0
0x7f906d400340
0x7ffeed730a30
0x7f906d400340
您会看到array
和&array
的值相同。但是pArray
和&pArray
具有不同的值。如果数组与指针相同,则数组的地址应与数组不同。
array
和&array
如何相同?如果array
和&array
相同,那么保存数组值的内存地址是什么?
答案 0 :(得分:79)
平原array
衰减为其第一个元素的指针,它等于&array[0]
。第一个元素也恰好从与数组本身相同的地址开始。因此&array == &array[0]
。
但是必须注意,类型是不同的:
&array[0]
的类型为int*
。&array
的类型为int(*)[5]
。 &array[0]
和&array
之间的关系如果更“图形化地”显示(添加了指针),则可能会更容易:
+----------+----------+----------+----------+----------+ | array[0] | array[1] | array[2] | array[3] | array[4] | +----------+----------+----------+----------+----------+ ^ | &array[0] | &array
尽管指针有所不同。指针pArray
指向某个内存,pArray
的值是该内存的位置。这就是使用pArray
时得到的。它也与&pArray[0]
相同。
使用&pArray
时,您会得到一个指向该指针的指针 。也就是说,您获得了变量pArray
本身的位置(地址)。其类型为int**
。
使用指针pArray
进行一些图形化处理
+--------+ +-----------+-----------+-----------+-----------+-----------+-----+ | pArray | ----> | pArray[0] | pArray[1] | pArray[2] | pArray[3] | pArray[4] | ... | +--------+ +-----------+-----------+-----------+-----------+-----------+-----+ ^ ^ | | &pArray &pArray[0]
[注意“数组”末尾的...
,这是因为指针不保留有关其指向的内存的信息。指针仅指向特定位置,即“数组”的“第一个”元素。将内存视为“数组”取决于程序员。]
答案 1 :(得分:1)
X的数组的行为必须类似于指向内存中X的连续列表的指针,就像指针一样。但是,在存储该数据的内存的任何地方都不能写它自己的地址和可写j。在使用显式指针的情况下,将为该地址(在本例中为堆栈)分配一个新的地址,但是对于数组,在堆栈上,编译器已经知道了内容的位置,因此不需要新的分配。
因此,将其视为没有索引的指针是不安全的。例如:pArray = nullptr; // This is a memory leak, unless a copy is taken, but otherwise fine.
array = nullptr; // This is will make the compiler upset