首先来用图片来抽象一下一维数组和二维数组。
从存储抽象图来看,一维数组和二维数组在存储方式上没什么不同,只不过是管理方式上不同。对于内存利用率而言,二者的内存利用率相同。
那么为什么要存在二维数组呢,首先明确一点,代码是给人看的,所以代码一方面的目的就是为了方便理解。举个例子,将10个同学分为两组,一组扫地一组拖地,显然如果将这两组人的数据定义为一维数组,最好的方式的定义两个一维数组,但是如果定义二维数组就可以只用定义一个二维数组即可int b[2][5],[0][x]时为拖地组,[1][x]时为扫地组,其次在记录直角坐标系时,使用二维数组也是非常方便的一种管理方式。
前面的文章说过,使用指针方式去访问数组,现在来说说二维数组如何使用指针进行访问。
a[0][0]=*(*(p+0)+0);
a[i][j]=*(*(p+i)+j);
二维数组经常用作显示器色彩填充,1920x1080的图片在不包含头信息的情况下可定义为a[1920][1080]。
二维数组填充方式:
int a[2][5]={{1,2,3,4,5},{6,7,8,9,10}};
数组指针指向二维数组的方式:
int (*p) [5];
p=a;
a表示二维数组中第一维数组的首元素地址相当于a[0]的地址。
访问方式:
*(*(p+1)+3);相当于a[1][3]意为第二组第四个元素
也可写作 *(p[1]+3)
现在定义变量如下:
int *p2=a[0]; 其地址为0xbcf71c
int *p3=a[1]; 其地址为0xbcf730
0xbcf730-0xbcf71c=20
20/4=5
不难看出p2和p3之间的元素相差了20个字节,由于定义数组类型为int类型,在32位系统中占4字节,所以这样绑定的指针之间相差了5个int类型变量的空间,也就是说,p2相当于a[0][0],而p3相当于a[1][0]。
那么指向二维数组的指针应该如何进行正确的绑定呢?
int *p5=a[1][1];X 这样的绑定是错误的
其原因在于编译器,由于编译器在计算时使用的是*(*(p+i)+j)的方式,也就是说,按照上面的绑定方式,其本质上是绑定了一个值也就是a[1][1]=7;所以正确的绑定方式是:
int *p6=&a[1][1];