#include <stdio.h>
int main(){
int array[] = {1,2,3};
printf("L00: array[0]=%d \n",array[0]);
printf("L01: array[1]=%d \n",array[1]);
printf("L02: array[2]=%d \n",array[2]);
printf("L03: &array[0]=%p \n",&array[0]);
printf("L04: &array[1]=%p \n",&array[1]);
printf("L05: &array[2]=%p \n",&array[2]);
printf("L06: array=%p \n",array);
printf("L07: &array=%p \n",&array);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这个程序中,L03,L06,L07和显示(&array
,array
,和&array[0]
,分别地)相同的存储器地址.
所以我很好奇"阵列"作为RAM中变量的位置.
如果RAM中没有"数组"的位置,它在哪里?
我必须写这么多次,但让我们再说一遍:
+----------+----------+----------+ | array[0] | array[1] | array[2] | +----------+----------+----------+ ^ ^ ^ ^ | | | | array | | | | | | | array + 0 array + 1 array + 2 | | | | | &array[0] &array[1] &array[2] | | | &array | | | &array + 0 &array + 1
从上面的"图像"可以看出,第一个元素可以通过五个指针(两个真正,array
衰减到&array[0]
,array + 0
等于)到达array
.
这些指针的类型可能不同但是:
&array
是类型的 int (*)[3]
&array + 0
等于,&array
因此是相同的类型&array[0]
是类型的 int *
array
衰败,&array[0]
因此属于同一类型array + 0
等于,array
因此是相同的类型当然有其他方法可以获得指向特定元素的指针,但它们实际上只是上述的变体.例如(&array)[0]
等于&array + 0
等于&array
.
另一件值得注意的事情是,对于任何指针或数组p
和索引i
,表达式p[i]
与...完全相同*(p + i)
.
你应该从中学到的最重要的事情是之间的差异array
和&array
.即使它们都指向相同的位置,它们的类型也不同,这使得它在语义上非常不同.
除了具有"自动存储持续时间"和本地范围之外,C标准没有规定存储阵列的位置.具有自动存储持续时间的较大变量几乎肯定存储在堆栈中.
至于为什么这3种不同形式的语法给出相同的地址:
array
,无论何时在表达式中使用,都会衰减为指向第一个元素的指针.使其100%相当于&array[0]
.&array
是一个指向整个数组的指针 - 一个数组指针.这是一种不同的类型,可用于对整个数组进行指针运算,但除此之外,它仍然指向数组开始的相同地址.(&array,array 和 &array[0]) 相同的内存地址。
是的,但它们的类型不同。
&array
属于 类型int (*) [3]
。array
是类型int [3]
(有时会衰减为指向第一个元素的指针)&array[0]
属于 类型int *
。根据定义,数组的内存分配是连续的,它从元素开始,&array[0]
一直到n-1
元素,n
即维度。
如果RAM中没有“数组”的位置,那么它在哪里?
如果“RAM”指的是物理内存地址,那么您的概念是错误的。大多数情况下,您不会直接使用任何物理内存,它是抽象给您的。打印的内存位置来自分配给程序的虚拟进程地址空间。
根据存储持续时间,您可以看到位置有所不同,即,如果数组具有自动存储,则它将驻留在函数堆栈(调用堆栈)上,如果它具有static
存储,则可能会位于.bss
段上。有时它也可能会被优化(在这种情况下,如果不使用的话),所以这取决于环境。除非编译器决定分配它,否则无法保证分配。