资源描述
二维数组与指针(教程)二维数组与指针1二维数组元素在内存中的存放方式在C+中,二维数组元素值在内存中是按行的顺序存放的。若定义二维整型数组a33,假设编译系统为数组a分配的内存空间从1000开始到1035为止,则数组中各元素a00a22在内存中按行存放次序如图7.6所示。因此,与一维数组类似,可用指针变量来访问二维数组元素。【例7.7】用指针变量输出二维数组各元素的值。#includevoidmain(void)inta33=1,2,3,4,5,6,7,8,9;int*p=&a00;将二维数组首地址赋给指针变量pfor(inti=0;i9;i+)cout*pt;输出二维数组中第i个元素值p+;/指针变量p加1,指向下一个元素程序执行后输出结果为:123456789但要用上述指针变量p访问二维数组中任意指定元素aij就觉得很不方便,为此C+设计者提供另外几种访问二维数组元素的方法,为了了解访问二维数组元素的方法,必须了解三个地址概念,即:二维数组行首地址、行地址、元素地址,现介绍如下。2二维数组行首地址二维数组各元素按行排列可写成如图7.7所示矩阵形式,若将第i行中的元素ai0、ai1、ai2组成一维数组ai(i=0丄2),则二维数组a33可看成是由三个一维数组元素a0、a1、a2组成。即:a33=(a0,a1,a2),其中:a0、a1、a2是分别表示二维数组a3的第0、1、2行元素。即:a0=(a00,a01,a02)a1=(a10,a11,a12)a2=(a20,a21,a22)因为数组名可用来表示数组的首地址,所以一维数组名ai可表示一维数组(ai0,ai1,ai2)的首地址&ai0,即可表示第i行元素的首地址。因此,二维数组a中第i行首地址(即第i行第0列元素地址)可用ai表示。由例7.6可知,一维数组的第i个元素地址可表示为:数组名+i。因此一维数组ai中第j个元素aij地址可表示为:ai+j,即:二维数组a中第i行第j列元素aij的地址可用ai+j来表示,而元素aij的值为:*(ai+j)。【例7.8】定义一个3行3列数组,输出每行的首地址及所有元素值。#includevoidmain(void)inta33=1,2,3,4,5,6,7,8,9;for(inti=0;i3;i+)coutai=ai=&ai0endl;for(intj=0;j3;j+)coutaij=*(ai+j)=aijendl;程序执行后输出:a0=0x0065FDD4=0x0065FDD4a00=1=1a01=2=2a02=3=3a1=0x0065FDE0=0x0065FDE0a10=4=4a11=5=5a12=6=6a2=0x0065FDEC=0x0065FDECa20=7=7a21=8=8a22=9=9由此例输出结果可看出ai=&aiO(i=0丄2),这表明ai确实可以表示第i行首地址(即第i行第0列地址)&ai0。读者应注意,由于数组在内存的地址是由操作系统动态分配,因此,实际输出的各行首地址并不会如图7.5所假设的从1000到1035。通常地址用十六进制数表示,如在本例中:第0行实际首地址是:a0=0x0065FDD4。第1行实际首地址是:al=0x0065FDE0。第2行实际首地址是:a2=0x0065FDEC。3二维数组行地址为了区别数组指针与指向一维数组的指针,C+引入了行地址的概念,并规定二维数组a中第i行地址用a+i或&ai表示,行地址的值与行首地址的值是相同的,即:a+i=&ai=ai=&ai0但两者类型不同,所以行地址a+i与&ai只能用于指向一维数组的指针变量,而不能用于普通指针变量,例如:inta33;int*p=a+0;则编译第二条指令时将会出错,编译系统提示用户p与a+0的类型不同。如果要将行地址赋数组指针变量,必须用强制类型转换,如:int*p=(int*)(a+0);关于指向一维数组的指针将在后文中介绍。二维数组名a可用于表示二维数组的首地址,但C+规定该首地址并不是二维数组中第0行第0列的地址(即a弄aOQ而是第0行的行地址,即a=a+0=&a0。4二维数组的元素地址与元素值知道了二维数组的行地址与行首地址后,可以讨论二维数组的元素地址。因为ai=*&ai=*(a+i),所以*(a+i)可以表示第i行的首地址。因此二维数组第i行首地址有三种表示方法:ai、*(a+i)、&ai0。由此可推知:第i行第j列元素aij的地址有四种表示方法:ai+j、*(a+i)+j、&ai0+j、&aij而第i行第j列元素aij值也有四种表示方法:*(ai+j)、*(*(a+i)+j)、*(&ai0+j)、aij现将二维数组有关行地址、行首地址、元素地址、元素值的各种表示方式总结归纳如表7.1所示:表7.1二维数组a的行地址、行首地址、元素地址、元素值的各种表示方式行地址、元素地址、元素值表示方式第i行行地址a+i、&ai第i行首地址(第i行第0列地址)ai、*(a+i)、&ai0元素aij的地址ai+j、*(a+i)+j、&ai0+j、&aij第i行第j列元素值*(ai+j)、*(*(a+i)+j)、*(&ai0+j)、aij为了加深读者对二维数组a的行地址、行首地址、元素地址、元素值的各种表示方式的理解,现举例如下:【例7.9】定义二维数组a33,用二种方式输出行地址,用三种方式输出行首地址,用四种方式输出所有元素地址及元素值。#includevoidmain(void)inta33=1,2,3,4,5,6,7,8,9;for(inti=0;i3;i+)cout&ai=&ai=a+iendl;输出第i行行地址coutai=ai=*(a+i)=&ai0endl;/行首地址for(intj=0;j3;j+)cout&aij=ai+j=*(a+i)+j=&ai0+j=&aijendl;输出元素aij的地址coutaij=*(ai+j)=*(*(a+i)+j)=*(&ai0+j)=aijendl;输出元素aij的值程序执行后输出结果为:&a0=0x0065FDD4=0x0065FDD4a0=0x0065FDD4=0x0065FDD4=0x0065FDD4&a00=0x0065FDD4=0x0065FDD4=0x0065FDD4=0x0065FDD4a00=1=1=1=1&a01=0x0065FDD8=0x0065FDD8=0x0065FDD8=0x0065FDD8a01=2=2=2=2&a02=0x0065FDDC=0x0065FDDC=0x0065FDDC=0x0065FDDCa02=3=3=3=3&a1=0x0065FDE0=0x0065FDE0a1=0x0065FDE0=0x0065FDE0=0x0065FDE0&a10=0x0065FDE0=0x0065FDE0=0x0065FDE0=0x0065FDE0a10=4=4=4=4&a11=0x0065FDE4=0x0065FDE4=0x0065FDE4=0x0065FDE4a11=5=5=5=5&a12=0x0065FDE8=0x0065FDE8=0x0065FDE8=0x0065FDE8a12=6=6=6=6&a2=0x0065FDEC=0x0065FDECa2=0x0065FDEC=0x0065FDEC=0x0065FDEC&a20=0x0065FDEC=0x0065FDEC=0x0065FDEC=0x0065FDECa20=7=7=7=7&a21=0x0065FDF0=0x0065FDF0=0x0065FDF0=0x0065FDF0a21=8=8=8=8&a22=0x0065FDF4=0x0065FDF4=0x0065FDF4=0x0065FDF4a22=9=9=9=9此例可说明表7.1中的二维数组a的行地址、行首地址、元素地址、元素值的各种表示方式是正确的。
展开阅读全文