创作不易,本篇文章如果帮助到了你,还请点赞支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ
目录
一些前导知识:
一、二维数组在内存中的存储形态
我们先定义一个二维数组(以一维 串的形式)
int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
为什么二维数组可以这样定义呢?二维数组不是平面 表格形式的吗?
原因是二维数组在内存中的存储形式是连续的。内存中并没有“表格”。
我们可以用int指针遍历数组元素,证明二维数组在内存中是连续的:
#include <stdio.h>
int main()
{
/* 二维数组在内存中的存储形态 */
int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
int* p = &arr[0][0];
for (int i = 0; i < 3 * 4; i++)
{
printf("%d ", *p++);
}
return 0;
}
在我们使用指针遍历数组时,二维数组中的元素成行排列,证明了二维数组在内存中是连续的。
在内存中也能查看:
二、二维数组名 地址常量用法
二维数组数组名代表首行元素的地址,&arr为整个二维数组的地址
以下是二维数组名的用法:
1)找到 某行的首地址
printf("%d %d %d\n", arr, arr + 1, arr + 2);
与一维数组不同的是:在二维数组中数组名代表了行地址
2)得到 某行的存储空间
printf("%d %d %d\n", *arr, *(arr + 1), * (arr + 2));
printf("%d %d %d\n", sizeof(* arr), sizeof(* (arr + 1)), sizeof(* (arr + 2)));
在一维数组中*arr就是得到了元素空间,取得了元素的值,而在二维数组中,*arr指得到了行的空间,并不会取到行元素的值。
在arr+1、arr+2偏移后,实际偏移了一整行的空间,所以地址相差16个字节,即一整行字节。
*arr、*arr+1、*arr+2代表的是第0行、第一行和第二行,所以字节数为16.
3)找到某行内--某列的地址
printf("%d %d %d\n", *(arr+1)+0, *(arr + 1)+1, *(arr + 1)+2);
在*(arr+1)取得到了行空间后,再进行偏移就是 在此行内向列偏移,得到列地址
4)得到某行 某列的存储空间
printf("%d %d %d\n", *(* (arr + 1) + 0), *(* (arr + 1) + 1), *(* (arr + 1) + 2));
由于*(arr+1)+0, *(arr + 1)+1已经取得了列地址,再加星号即可取得对应列空间,即取得了该行该列元素的值。
先找行再找列的过程可以理解为:
找教室的过程:先找到楼层 (找到行) 得到了一层的空间(行空间)
然后在本层内找到房间(在行空间得到列空间)
&找到行地址 -> *得到行空间 -> &找到列地址 -> *得到列空间 !!!
在之前讲过(深度理解 [ ]运算符) [ ] 是计算过程: 参考地址 [ 偏移量 ] === *(参考地址 +偏移量) 我们可以将上面的代码进行变换 将*( + )变换成 [ ] 结果让人大吃一惊:
//得到 某行的存储空间
printf("%d %d %d\n", *arr, *(arr + 1), *(arr + 2));
printf("%d %d %d\n", arr[0], arr [ 1], arr [ 2]);
//:找到某行内--某列的地址
printf("%d %d %d\n", *(arr + 1) + 0, *(arr + 1) + 1, *(arr + 1) + 2);
printf("%d %d %d\n", arr [ 1] + 0, arr [ 1] + 1, arr [ 1] + 2);
//:得到某行 某列的存储空间
printf("%d %d %d\n", *(*(arr + 1) + 0), *(*(arr + 1) + 1), *(*(arr + 1) + 2));
printf("%d %d %d\n", arr [ 1] [ 0], arr [ 1] [ 1], arr [ 1] [ 2]);
*到[ ]的变换过程: *(x + v)将 *(+)都去掉 变成 x v,再在v左右加上[ ]
在经过了*()变成 [ ]的运算后,获得了arr[ ]的形式,通过这个变换,将对二维数组理解更加深入
arr[0], arr [ 1], arr [ 2]是 0,1,2行的存储空间,arr [ 1] + 0, arr [ 1] + 1, arr [ 1] + 2 是行内列的偏移,arr [ 1] [ 0], arr [ 1] [ 1], arr [ 1] [ 2]就得到了列的空间,同时也是数组下标法的某元素值!
三、&arr取整个二维数组的地址
printf("%d %d\n", &arr, &arr + 1); //差48 12个整数
四、数组指针在二维数组的用法
1)利用指向一维数组的指针 遍历每一行的首地址
在二维数组中,arr指得到了行的地址。
int(*ph1)[4] = arr;
for (int i = 0; i < 3; i++)
{
printf("%d \n", ph1++);
}
2)利用指向一维数组的指针 遍历每一行 每一个元素成员
利用指向一维数组的指针再对列偏移得到元素空间:
int(*ph2)[4] = arr;
for (int i = 0; i < 3; i++)
{
printf("%d %d %d %d\n",*(*ph2+0),*(*ph2+1),(*ph2)[2],*(* ph2 + 3));
ph2++;
}
3)利用指向二维数组的指针 遍历每一行 每一个元素成员
利用二维数组指针直接得到各元素空间:
int(*pm)[3][4] = &arr;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d %d %d ",arr[i][j],(*pm)[i][j],*(*(*pm + i)+j));
}
printf("\n");
}