#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;
}
在此程序中,L03,L06和L07分别显示(&array
,array
和&array[0]
)相同的内存地址。
所以我很好奇“数组”作为RAM变量的位置。
如果RAM中没有“数组”的位置,它在哪里?
答案 0 :(得分:8)
C11标准规范没有说明RAM,IIRC(但请自行检查,阅读n1570)。在大多数operating systems上,process有一个virtual address space(您的程序将在该空间中运行,而不一定在RAM中运行)。
您的数组(可能)位于call stack。
我猜一个假设的optimizing compiler可能足够巧妙,可以把它放在别处(但我不能说这样的编译器)。
答案 1 :(得分:7)
我必须多次写这篇文章,但让我们再来一次:
+----------+----------+----------+ | 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
等于{{ 1}})。
这些指针的类型虽然可能不同:
array
的类型为&array
int (*)[3]
等于&array + 0
,因此属于同一类型&array
的类型为&array[0]
int *
衰减到array
因此属于同一类型&array[0]
等于array + 0
,因此属于同一类型当然有其他方法可以获取指向特定元素的指针,但它们实际上只是上述的变体。例如,array
等于(&array)[0]
,等于&array + 0
。
另一件值得注意的事情是,对于任何指针或数组&array
和索引p
,表达式i
与{完全相同} {1}}。
您应该从中学到的最重要的事情是p[i]
和*(p + i)
之间的区别。即使它们都指向相同的位置,它们的类型也不同,这使得它在语义上非常不同。
答案 2 :(得分:5)
C标准没有规定存储阵列的位置,除了它具有&#34;自动存储持续时间&#34;和当地范围。具有自动存储持续时间的较大变量几乎肯定存储在堆栈中。
至于为什么这3种不同形式的语法给出相同的地址:
array
,无论何时在表达式中使用,都会衰减为指向第一个元素的指针。使其100%等同于&array[0]
。&array
是指向整个数组的指针 - 一个数组指针。这是一种不同的类型,可用于对整个数组进行指针运算,但除此之外,它仍然指向数组开始的相同地址。答案 3 :(得分:4)
(&amp; array,array和&amp; array [0])相同的内存地址。
是的,但它们的类型不同。
&array
的类型为int (*) [3]
。array
属于int [3]
类型(有时会衰减到指向第一个元素的指针)&array[0]
的类型为int *
。根据定义,数组的内存分配是连续的,它从&array[0]
开始,最多为n-1
个元素,n
为维度。
如果RAM中没有“数组”的位置,它在哪里?
如果“RAM”是指物理内存地址,那么你的概念是错误的。大多数情况下,您不是直接使用任何物理内存,而是抽象给您。打印的内存位置来自分配给程序的虚拟进程地址空间。
根据存储持续时间,您可以看到位置不同,即,如果阵列具有自动存储,它将驻留在功能堆栈(调用堆栈)上,它可能有static
存储,可能它将在.bss
部分。有时它也可能会被优化(不是在这种情况下,如果不使用),所以这取决于环境。除非编译器决定分配它,否则无法保证分配。