C 二维数组名第一个元素
每天一小时的C编程有这样一句话:C 二维数组名第一个元素,c,arrays,multidimensional-array,C,Arrays,Multidimensional Array,每天一小时的C编程有这样一句话: 与一维数组一样,多维数组的名称是指向第一个数组元素的指针 #包括 int m[2][4]; int main(){ printf(“%p\n”,m);//1 printf(“%p\n”&(m[0]);//2 printf(“%p\n”,m[0]);//3 printf(“%p\n”,&m[0][0]);//4 } 这将为所有语句打印相同的值。根据引文,1==2和3==4是有意义的。但我不明白2==3是怎么回事。m[0]的地址怎么可能与m[0]相同?第一个维度将
与一维数组一样,多维数组的名称是指向第一个数组元素的指针
#包括
int m[2][4];
int main(){
printf(“%p\n”,m);//1
printf(“%p\n”&(m[0]);//2
printf(“%p\n”,m[0]);//3
printf(“%p\n”,&m[0][0]);//4
}
这将为所有语句打印相同的值。根据引文,1==2和3==4是有意义的。但我不明白2==3是怎么回事。
m[0]
的地址怎么可能与m[0]
相同?第一个维度将存储子阵列(行)的地址
例如,您有m[2][4]
,因此m[0]
计算包含m[0]中元素的第一行的地址[0]
至m[0][3]
和m[1]
的计算结果是第二行的地址包含m[1]中的元素[0]
至m[1][3]
如果您尝试打印m[0]
和m[1]
,您将看到地址差异是相隔m[0]
字节的行的总大小。当分配二维(或任意维)数组时,它只会占用其元素的内存。(内存不会分配给数组名或任何其他数组元素,如m[0]
和m[1]
,在您的情况下,它们的作用类似于常量指针)
因为不会有任何物理内存分配给这些(实际上甚至不需要),所以在尝试打印这些时,您将获得相同的地址。在您的情况下,
由于它是一个二维数组,因为m
指向m[0]
,而m[0][0]
又指向m[0]
,所有这些数组的获取地址将给出相同的值(同样对于m[1]
和m[1][0]
)
**为了更好地理解,请参见此(如果您打印这些内容,将是这样的)
*value
是m[0][0]的值
这里,,
m
和m[0]
的作用类似于指针,但不是物理实现的(不占用内存),编译器处理如何处理这些指针
*虽然我已经展示了0x100
包含0x100
对于m
和m[0]
,0x100
实际上包含m[0][0]
的数据/值,但是如果您执行任何操作,编译器就是这样处理它们的
**正因为如此,int*p=malloc(n*sizeof(int))这是可能的,代码<>代码>代码占用内存,指向数组的起始地址。如果考虑<代码> P<代码>代码> int const *p/代码>,可以将其视为一个没有动态分配的正常数组。 数组只包含数据,不包含任何其他内容。此数据有地址。它从哪里开始-这是第一个元素的地址
“多维数组的名称是指向第一个数组元素的指针”过于简化,并不正确。数组不是指针,指针也不是数组
但是,无论何时在表达式中使用数组(任何维度)的名称,都会生成指向数组第一个元素的临时指针。这通常被称为“数组衰减为指针”
现在,这些行之间唯一不同的是指针的类型:
int[2][4]
类型的数组衰减为指向第一个元素的指针。2D数组中的第一个元素是int[4]
类型的1D数组。指向此类数组的指针是数组指针,int(*)[4]
&m[0]
给出了第一个元素的地址,即第一个1D数组的地址。因此这完全等同于1)
m[0]
给出第一个元素,仍然是1D数组。它衰减为指向其第一个元素的指针。int[4]
的第一个元素是int
,因此我们得到一个指向该元素的指针,即int*
&m[0][0]
给出指向第一个数组的第一个元素的指针,即int*
。相当于3)
所有这些指针类型都将具有相同的地址,这仅仅是因为2D数组从其第一项1D数组的相同地址开始。它的起始地址与它的第一个项相同,即第一个整数
各种不同的指针类型只是高级语言语法。这些类型在机器代码中并不是持久存在的,在机器代码中,所有的东西都是原始地址。因为,这就是它的实现方式,也因为它的工作原理。
int*p=malloc(n*sizeof(int))。尝试打印&m
,也会产生相同的结果。因为对于数组的情况,所有这些都没有实际实现,也不占用内存,但仍然可以用作指向数组(或地址)的指针:转换说明符%p
仅为void
-指针定义,因此代码应该类似于printf(“%p\n”,(void*)m)代码>。对printf()
的其他三个调用也是如此。否则将调用未定义的行为。亲爱的上帝,这个问题已经以多少种方式提出了?“与一维数组一样,多维数组的名称是指向第一个数组元素的指针。”-->否。数组不是指针。在选定的情况下,数组转换为第一个元素的指针,但是m
仍然是一个数组。很好。对于另一个错误:“m[0]存储第一行的地址”,它实际上不存储它。发生的情况称为m[0]
“衰减到”第一行的地址。我同意值m[0]不是从存储器读取的,而是在引用时计算出来的
#include <stdio.h>
int m[2][4];
int main() {
printf("%p\n", m); // 1
printf("%p\n", &(m[0])); // 2
printf("%p\n", m[0]); // 3
printf("%p\n", &m[0][0]); // 4
}
_____ _____ _____
|0x100| --> |0x100| --> |value|
0x100|_____| 0x100|_____| 0x100|_____|
m m[0] m[0][0]