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