C 二维/多维数组的内存映射

C 二维/多维数组的内存映射,c,arrays,memory,memory-management,2d,C,Arrays,Memory,Memory Management,2d,有人能直观地解释一下2D数组是如何存储在内存中的吗 a、&a、&a[0]、a[0]都有相同的地址。。。 在某种程度上,它就像一个指向自身的指针……这不可能是正确的。。。 这已经困扰了我将近一年,在网上搜索也让我找不到合适的答案。。。。。非常感谢您的帮助……谢谢 enter code here #include<stdio.h> int main() { int a[2][3]={10,20,30,40,50,60}; int row =0,col=0;

有人能直观地解释一下2D数组是如何存储在内存中的吗 a、&a、&a[0]、a[0]都有相同的地址。。。 在某种程度上,它就像一个指向自身的指针……这不可能是正确的。。。 这已经困扰了我将近一年,在网上搜索也让我找不到合适的答案。。。。。非常感谢您的帮助……谢谢

enter code here

#include<stdio.h>

int main()
{
    int a[2][3]={10,20,30,40,50,60};

    int row =0,col=0;

    printf("&a = %d ",&a);    
    printf("\na = %d ",a);
    printf("\n&a[0] = %d ",&a[0]);
    printf("\na[0] = %d ",a[0]);
    printf("\n&a[1] = %d ",&a[1]);
    printf("\na[1] = %d ",a[1]);
    printf("\n&a[0][0] = %d ",&a[0][0]);

    int *p;
    printf("\n\n sizeof(p) = %d ",sizeof(p) );

    printf("\n\n sizeof(a) = %d ",sizeof(a) );
    printf("\n\n sizeof(&a) = %d ",sizeof(&a) );
    printf("\n\n sizeof(&a[0]) = %d ",sizeof(&a[0]) );
    printf("\n\n sizeof(a[0]) = %d ",sizeof(a[0]) );
    printf("\n\n sizeof(&a[1]) = %d ",sizeof(&a[1]) );
    printf("\n\n sizeof(a[1]) = %d ",sizeof(a[1]) );
    printf("\n\n sizeof(&a[0][0]) = %d ",sizeof(&a[0][0]) );
}

别把我指给。。。这没有帮助…

因此数组
a
是一个占用内存块的对象:

| a                                                         |
这是一个长度为2的数组,因此如果我们绘制组成它的元素,它看起来如下:

| a[0]                        | a[1]                        |
| a[0][0] | a[0][1] | a[0][2] |
| a[0][0] | a[0][1] | a[0][2] | a[1][0] | a[1][1] | a[1][2] |
a[0]
又是一个长度为3的数组,如下所示:

| a[0]                        | a[1]                        |
| a[0][0] | a[0][1] | a[0][2] |
| a[0][0] | a[0][1] | a[0][2] | a[1][0] | a[1][1] | a[1][2] |
a[1]
看起来是一样的,因此我们可以重新绘制数组
a
如下:

| a[0]                        | a[1]                        |
| a[0][0] | a[0][1] | a[0][2] |
| a[0][0] | a[0][1] | a[0][2] | a[1][0] | a[1][1] | a[1][2] |
请注意,
a
a[0]
a[0][0]
都位于内存中的同一点:对象
a
的起点。但是,它们有不同的大小:
a
是整个“2D数组”,
a[0]
是一个常规数组,
a[0][0]
是一个单独的`int'

这就解释了为什么
&a
&a[0]
&a[0][0]
是相同的地址(尽管它们有不同的类型)-它们是位于内存中同一点的事物的地址

此外,还有一条规则,如果在一元
&
sizeof
运算符的主题之外的表达式中对数组求值,则它求值为指向其第一个元素的指针:也就是说,使用普通
a
相当于
&a[0]
。由于
a[0]
也是一个数组,因此使用普通
a[0]
相当于
&a[0][0]
。这就解释了为什么
a
a[0]
还计算到与
&a
&a[0]
&a[0][0]
相同的地址

一个数组的地址和该数组中第一个元素的addAddress是相同的这一事实并不令人惊讶:同样的事情也发生在
struct
上。鉴于:

struct { int a; int b; } x;

您会发现
&x
&x.a
是相同的地址(尽管类型不同)。

因此数组
a
是一个占用内存块的对象:

| a                                                         |
这是一个长度为2的数组,因此如果我们绘制组成它的元素,它看起来如下:

| a[0]                        | a[1]                        |
| a[0][0] | a[0][1] | a[0][2] |
| a[0][0] | a[0][1] | a[0][2] | a[1][0] | a[1][1] | a[1][2] |
a[0]
又是一个长度为3的数组,如下所示:

| a[0]                        | a[1]                        |
| a[0][0] | a[0][1] | a[0][2] |
| a[0][0] | a[0][1] | a[0][2] | a[1][0] | a[1][1] | a[1][2] |
a[1]
看起来是一样的,因此我们可以重新绘制数组
a
如下:

| a[0]                        | a[1]                        |
| a[0][0] | a[0][1] | a[0][2] |
| a[0][0] | a[0][1] | a[0][2] | a[1][0] | a[1][1] | a[1][2] |
请注意,
a
a[0]
a[0][0]
都位于内存中的同一点:对象
a
的起点。但是,它们有不同的大小:
a
是整个“2D数组”,
a[0]
是一个常规数组,
a[0][0]
是一个单独的`int'

这就解释了为什么
&a
&a[0]
&a[0][0]
是相同的地址(尽管它们有不同的类型)-它们是位于内存中同一点的事物的地址

此外,还有一条规则,如果在一元
&
sizeof
运算符的主题之外的表达式中对数组求值,则它求值为指向其第一个元素的指针:也就是说,使用普通
a
相当于
&a[0]
。由于
a[0]
也是一个数组,因此使用普通
a[0]
相当于
&a[0][0]
。这就解释了为什么
a
a[0]
还计算到与
&a
&a[0]
&a[0][0]
相同的地址

一个数组的地址和该数组中第一个元素的addAddress是相同的这一事实并不令人惊讶:同样的事情也发生在
struct
上。鉴于:

struct { int a; int b; } x;

您会发现
&x
&x.a
是相同的地址(尽管类型不同)。

除非它是
大小的操作数或一元
&
运算符,或者是用于初始化声明中另一个数组的字符串文本,类型为“T
的N元素数组”将转换为“指向T的指针”类型的表达式,表达式的值将是数组中第一个元素的地址

假设以下内存映射(假设小尾端,4字节
int
s;从稀薄的空气中提取地址):

项目地址00 01 02 03子数组子数组元素 ---- ------- -- -- -- -- --------- ----------------- a 0xfffebc00 0a a[0]a[0][0] 0xfffebc04 00 14 a[0][1] 0xfffebc08 00 1e a[0][2] 0xfffebc0c 00 28 a[1]a[1][0] 0xfffebc10 00 32 a[1][1] 0xfffebc14 00 3c a[1][2] 按照上述规则,表达式
a
将从类型“int的3元素数组的2元素数组”转换为“指向int的3元素数组的指针”,表达式的值将是数组的第一个元素的地址。
a
的第一个元素是
a[0]
,而
a[0]
的地址是
0xfffebc00

类似地,表达式
a[0]
将从类型“3元素数组的
int
”转换为“指针指向
int
”,其值将是数组的第一个元素的地址。
a[0]
的第一个元素是
a[0][0]
,其地址是…
0xfffebc00

表达式
&a
是ru的一个例外