一、二维数组
二维数组内存中的分布:
对于C语言来说,本质上没有一维数组二维数组之分,全部都是1维数组
二维数组本质上也是一个-维数组,特别就是这个数组的每一个元素都是一个一维数组.
二维数组在内存中分布也是一个元素一 个元素的按下 挨着 存储.
二、二维数组的数组名
二维数组的数组名是一个地址常量,数组名就是首元素的地址;
数组名的值 == 首元素的地址 == 整个数组的地址 ,详情见图:(3址合一)
对于一个二维数组:arr[3][3];
将他看成是由3个长度为3的一维数组构成的就好;
那么arr[0]、arr[1]、arr[2]分别当做3个一维数组的数组名
下面用代码来验证他们的地址是否相等?
#include<stdio.h>
int main(int argc,char* argv[])
{
int arr[3][3]={1,2,3,4,5,6,7,8,9}; //定义一个二维数组
//question1:验证3址是否合一
printf("arr=%p\n",arr); //数组名的值 0x7ffd3df678f0
printf("&arr[0]=%p\n",&arr[0]); //首元素的地址 0x7ffd3df678f0
printf("&arr=%p\n",&arr); //整个数组的地址 0x7ffd3df678f0
if( (arr==&arr) && (arr==&arr[0]) && (&arr[0]== &arr) )
{
printf("数组名的值 == 数组首元素的值 == 整个数组的地址。\n\n");
}
//question2:验证了三址合一后吗,我们验证他们的含义是一样的吗?
//如果三者含义一直,偏移量也将一致
//arr+1偏移多少个字节
//&arr+1偏移多少个字节
//&arr[0]+1偏移多少个字节
printf("arr+1=%p\n",arr+1); //0x7ffd3df678fc
printf("&arr[0]+1=%p\n",arr[0]+1); //0x7ffd3df678fc
printf("&arr+1=%p\n",&arr+1); //0x7ffd3df67914
if(arr+1==arr[0]+1)
{
printf("数组名和数组首元素地址的含义一一致。\n");
}
if(arr+1 = &arr+1)
{
printf("数组名和整个数组地址的含义不一致。\n");
}
if(&arr+1 != arr[0]+1)
{
printf("整个数组的地址和数组首元素地址的含义不一致。\n");
}
return 0;
}
总结
int a; //系统将分配一个1个int类型字节 &a是获取a的地址,
并告知系统我占的字节数是int类型个字节数 ;
a+1
表示的是数值上的加1 假定a=5 那么a+1=6.
int a[5]; //系统将分配5个连续的int类型字节数,
单个元素的类型为int;
&a是获取整个数组a的地址,并告知系统我占的字节数是int[5]个字节数;
a是数组的首元素地址,首元素(数组中每个元素类型一致,
前文中提到该二维数组的单个元素类型为int) 类型为int型,
在数组中 a+1 的偏移量 就是单个变量在地址中所占的内存;
所以a+1 即偏移量为 移动一个int类型的字节数.
int a[5][5]; //系统将分配5个连续的int[5]类型字节数,
单个元素的类型为int[5];
&a是获整个数组a的地址,并告知系统我占的字节数是int[5][5]个字节数;
a是数组首元素的地址,首元素(数组中每个元素类型一致,
前文中提到该二维数组的单个元素类型为int[5])类型为int [5];
所以 a+1 即偏移量 移动的字节数就是int [5]个字节数.
3、数组名的相关运算
1 | 2 | 3 |
---|---|---|
4 | 5 | 6 |
7 | 8 | 9 |
a. arr+1:移动12个字节:arr是首元素地址,首元素类型为int[3];
b. &arr+1:移动36个字节,&arr是获取整个数组的地址
c. *arr+1 :移动4个字节
d. *(*(arr+1)+1)+1: 值为:6