如何在内存中代表C阵列?

Dan*_*cco 26 c arrays memory-management

我相信如果你使用C,我理解在内存中如何表示正常的变量和指针.

例如,很容易理解指针Ptr将具有一个地址,并且它的值将是一个不同的地址,这是它指向的内存空间.以下代码:

int main(){
    int x = 10;
    int *Ptr;
    Ptr = &x;
return 0;
}
Run Code Online (Sandbox Code Playgroud)

将在内存中具有以下表示:

+---------------------+-------------+---------+
| Variable Name       | Address     | Value   | 
+---------------------+-------------+---------+
| x                   | 3342        | 10      |
+---------------------+-------------+---------+
| Ptr                 | 5466        | 3342    |
+---------------------+-------------+---------+
Run Code Online (Sandbox Code Playgroud)

但是我发现很难理解数组如何在内存中表示.例如代码:

int main(){
    int x[5];
        x[0]=12;
        x[1]=13;
        x[2]=14;

    printf("%p\n",(void*)x);
    printf("%p\n",(void*)&x);

return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出相同的地址两次(为简单起见10568).意思是x ==&x.然而,*x(或数组符号中的x [0])等于12,*(x + 1)(或数组符号中的x [1])等于13,依此类推.怎么能代表这个?一种方法可能是这样的:

+---------------------+-------------+----------+----------------------+
| Variable Name       | Address     | Value    | Value IF array       |
+---------------------+-------------+----------+----------------------+
| x                   | 10568       | 10568    | 12                   |
+---------------------+-------------+----------+----------------------+
|                     | 10572       |          | 13                   | 
+---------------------+-------------+----------+----------------------+
|                     | 10576       |          | 14                   | 
+---------------------+-------------+----------+----------------------+
|                     | 10580       |          | trash                | 
+---------------------+-------------+----------+----------------------+
|                     | 10584       |          | trash                | 
+---------------------+-------------+----------+----------------------+
Run Code Online (Sandbox Code Playgroud)

这接近发生的事情还是完全关闭?

caf*_*caf 33

数组是一个连续对象块,中间没有空格.这意味着x在您的第二个示例中,在内存中表示为:

+---------------------+-------------+---------+
| Variable Name       | Address     | Value   | 
+---------------------+-------------+---------+
| x                   | 10568       | 12      |
|                     |             +---------+
|                     |             | 13      |
|                     |             +---------+
|                     |             | 14      |
|                     |             +---------+
|                     |             | ??      |
|                     |             +---------+
|                     |             | ??      |
+---------------------+-------------+---------+
Run Code Online (Sandbox Code Playgroud)

也就是说,x是五个int大,并有一个地址.

关于数组的奇怪部分不在于它们是如何存储的 - 它们是如何在表达式中进行评估的.如果在某个地方使用的数组名称不是一元&sizeof运算符的主题,则它将计算其第一个成员的地址.

也就是说,如果你只是写x,你会得到一个类型为10568的值int *.

另一方面,如果你编写&x,那么特殊规则不适用 - 因此&操作符就像通常那样工作,这意味着它获取数组的地址.在该示例中,这将是具有类型的值10568 int (*)[5].

原因x == &x是数组的第一个成员的地址必须等于数组本身的地址,因为数组以其第一个成员开头.


Ray*_*hen 22

你的图表是正确的.周围的奇怪&x与数组如何在内存中表示无关.它与array->指针衰减有关.x在值上下文中自身衰变为指向其第一个元素的指针; 即,它相当于&x[0].&x是指向数组的指针,并且两者在数值上相等的事实只是说数组的地址在数值上等于其第一个元素的地址.