任何人都可以解释直观关于2D数组如何存储在内存中: a,& a,& a [0],a [0]都有相同的地址...... 这似乎是一个指针指向自己的指针......而且不能正确...... 这已经让我困扰了将近一年,在网上搜索也让我无法回答.....帮助真的很感激.... thanx
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 = 2293536
a = 2293536
&a[0] = 2293536
a[0] = 2293536
&a[1] = 2293548
a[1] = 2293548
&a[0][0] = 2293536
sizeof(p) = 4
sizeof(a) = 24
sizeof(&a) = 4
sizeof(&a[0]) = 4
sizeof(a[0]) = 12
sizeof(&a[1]) = 4
sizeof(a[1]) = 12
sizeof(&a[0][0]) = 4
不要把我推荐给那些没有帮助的Memory map for a 2D array in C ......
答案 0 :(得分:5)
所以数组a
是一个占用内存块的对象:
| a |
这是一个长度为2的数组,所以如果我们绘制构成它的元素,它看起来像这样:
| a[0] | a[1] |
a[0]
又是一个长度为3的数组,看起来像这样:
| a[0][0] | a[0][1] | a[0][2] |
a[1]
看起来一样,所以我们可以重新绘制数组a
,如下所示:
| 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]
相同的地址。
数组的地址和该数组中第一个元素的adddress相同的事实并不令人惊讶:同样的事情也发生在struct
上。给出:
struct { int a; int b; } x;
您会发现&x
和&x.a
是相同的地址(虽然类型不同)。
答案 1 :(得分:1)
除非它是sizeof
_Alignof
或一元&
运算符的操作数,或者是用于初始化声明中的另一个数组的字符串文字,否则 “N-element array of T
”类型的表达式将转换为“指向T
的指针”类型的表达式,表达式的值将是第一个元素的地址在数组中。
假设以下内存映射(假设是little-endian,4字节int
;地址是凭空消失的:
Item Address 00 01 02 03 Sub array Sub array element ---- ------- -- -- -- -- --------- ----------------- a 0xfffebc00 00 00 00 0a a[0] a[0][0] 0xfffebc04 00 00 00 14 a[0][1] 0xfffebc08 00 00 00 1e a[0][2] 0xfffebc0c 00 00 00 28 a[1] a[1][0] 0xfffebc10 00 00 00 32 a[1][1] 0xfffebc14 00 00 00 3c a[1][2]
按照上面提到的规则,表达式 a
将从“{-1}}的3元素数组的2元素数组”转换为“指向3元素数组int
“,表达式的值将是数组第一个元素的地址。 int
的第一个元素是a
,a[0]
的地址是a[0]
。
类似地,表达式0xfffebc00
将从类型“{-1}}的3元素数组”转换为“指向a[0]
的指针”,其值将是第一个的地址数组的元素。 int
的第一个元素是int
,其地址是...... a[0]
。
表达式a[0][0]
是上述规则的例外之一。在这种情况下,0xfffebc00
在应用&a
运算符之前不会转换为指针类型;表达式的类型是“指向{-1}}(a
)的3元素数组的2元素数组的指针,其值是&
的地址,它是... 。int
。
类似地,表达式int (*)[2][3]
具有类型“指向a
的3元素数组的指针”,其值为0xfffebc00
的地址,即... {{1} }。
希望&a[0]
的类型和价值应该是显而易见的。
是的,表达式int
,a[0]
,0xfffebc00
,&a[0][0]
,a
和&a
都会产生相同的值,但其类型不同:*a
,a[0]
,&a[0]
,&a[0][0]
,int (*)[3]
和int (*)[2][3]
,分别