一、二维数组的存储
1.例如:float a[3][5] 在内存中申请一段连续的内存,按行连续存储数据:
a[0][0],a[0][1],a[0][2],a[0][3],a[0][4],a[1][0],a[1][1],a[1][2],a[1][3],a[1][4],a[2][0],a[2][1],a[2][2],a[2][3],a[2][4]
2.输出二维数组元素的两种方法:
#include <stdio.h>
int main()
{
int a[3][4] = { {1,2,3,4},{11,12,13,14},{21,22,23,24} };
//输出a[2][1]地址:
printf("%p\n", &a[2][1]); //直接取元素的地址
printf("%p\n", &a[0][0] + 2 * 4 + 1); //通过首元素地址偏移得到;
printf("%p\n", a + 2 * 4 + 1); //错误,二维数组名运算,按行进行加减
}
运行结果:
0095FDC4
0095FDC4
0095FE30
二、深入理解二维数组
1、二维数组看作是元素是一维数组的一维数组
2、例:int a[3][4];
可以将 a 看作是一维数组,它有3个元素:a[0],a[1]和a[2]
每个元素a[i]又是一个包含4个元素的一维数组
a[i]是一维数组的名字,其值是第i行的起始地址
三、体会下面程序
#include <stdio.h>
int main()
{
int a[3][4] =
{
{1,2,3,4},
{11,12,13,14},
{21,22,23,24},
}; //这个二维数组可看作是包含三个“数组”元素的一维数组{a[0],a[1],a[2]}
//以下四种输出都是元素a[2][3]的地址
printf("%p\n", &a[2][3]); //直接取元素的地址
printf("%p\n", a[2] + 3);
//a[2]为二维数组中的一个元素,这个元素是数组,a[2]是这个数组名代表首元素a[2][0]地址;
printf("%p\n", *(a + 2) + 3);
//a是二维数组名代表&a[0],a+2是按行运算为&a[2],*(a+2)=&(&a[2])=a[2],后续同上;
//=>*((&a[0]+2)+3) =>*(&a[2])+3 =>a[2]+3 =>&a[2][3];
printf("%p\n", &a[0][0] + 2 * 4 + 3); //按首元素地址偏移理解,程序中不用乘占用字节数
//以下四种输出都是元素a[2][3]的值
printf("%d\n", *(&a[2][3]));
printf("%d\n", *(a[2] + 3));
printf("%d\n", *(*(a + 2) + 3));
printf("%d\n", *(&a[0][0] + 2 * 4 + 3));
}