数组变量在哪里用C语言存储?

mal*_*lea 4 c arrays pointers

#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中没有"数组"的位置,它在哪里?

Bas*_*tch 8

C11标准规范不说的RAM,IIRC任何东西(但检查自己,读n1570).在大多数操作系统上,进程具有虚拟地址空间(并且您的程序将在该空间中运行,而不一定在RAM中运行).

您的阵列(可能)位于调用堆栈中.

我想一个假设的优化编译器可能足够聪明,可以把它放在别处(但我不能说这样的编译器).


Som*_*ude 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等于)到达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.即使它们都指向相同的位置,它们的类型也不同,这使得它在语义上非常不同.


Lun*_*din 5

除了具有"自动存储持续时间"和本地范围之外,C标准没有规定存储阵列的位置.具有自动存储持续时间的较大变量几乎肯定存储在堆栈中.

至于为什么这3种不同形式的语法给出相同的地址:

  • array,无论何时在表达式中使用,都会衰减为指向第一个元素的指针.使其100%相当于&array[0].
  • &array是一个指向整个数组的指针 - 一个数组指针.这是一种不同的类型,可用于对整个数组进行指针运算,但除此之外,它仍然指向数组开始的相同地址.


Sou*_*osh 4

(&array,array 和 &array[0]) 相同的内存地址。

是的,但它们的类型不同。

  • &array属于 类型int (*) [3]
  • array是类型int [3](有时会衰减为指向第一个元素的指针)
  • &array[0]属于 类型int *

根据定义,数组的内存分配是连续的,它从元素开始,&array[0]一直到n-1元素,n即维度。

如果RAM中没有“数组”的位置,那么它在哪里?

如果“RAM”指的是物理内存地址,那么您的概念是错误的。大多数情况下,您不会直接使用任何物理内存,它是抽象给您的。打印的内存位置来自分配给程序的虚拟进程地址空间。

根据存储持续时间,您可以看到位置有所不同,即,如果数组具有自动存储,则它将驻留在函数堆栈(调用堆栈)上,如果它具有static存储,则可能会位于.bss段上。有时它也可能会被优化(在这种情况下,如果不使用的话),所以这取决于环境。除非编译器决定分配它,否则无法保证分配。