指针与一维数组的关系:
1.一维数组(int型):int buf[5]={1,2,3,4,5};
数组名就是首地址,数组是一块连续同类型的空间,因此定义一个指针指向数组首地址就可以表示数组。
int *pa=buf;
但是一维数组只有一行,并没有列。
指针与二维数组:
2.二维数组(int型):int buf[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}
int *pb=buf;
二维数组的指针分为行指针和列指针,pb指向的是第一行,pb+1指向的是第一行,验证方法是将pb和pb+1打印出来,看他们的地址是否连续,即相隔sizeof(int)。
pb[0]或者是*pb是列指针,指向第一行的第一列,或者可以理解为pb[0],pb[1],pb[2]是每一行的首地址;
注:分别打印&buf[0][0], buf ,buf[0],发现他们的地址都相同,但是意义不同,如图所示,这三个指针分别代表第一行第一个元素的地址,第一行指针,第一行的列指针(第一行元素首地址)
引用二维数组里面的元素需要将下标精确到行和列,例如第2行第3个元素buf[1][2],这个表示方法大家都知道。那么如何用指针表示呢,我们可以用拆分的方法。表示方法有8种,严格来说只有四种。
1.*(pb[1]+2) pb[1]代表列指针,指向第二行第1列,向右移两个位置再取值
2.*(pb+1)[2] pb+1行指针,指向第二行,*(pb+1)表示第二行首地址。
注:有人感到疑惑,* 不是引用地址里面的元素吗,那么*(pb+1)不就是第二行的元素?请注意第二行是一个数组,下标法和指针法都是引用数组里面的一个元素,不可能直接是取出一组数组,这个地方记住是取第二行的首地址就行了。
3.pb[1][2]
4.*(*(pb+1)+2)
二维数组的逻辑地址如上图所示,但是二维数组在物理空间里面的地址跟一维数组是一样的。验证方法打印每一行最后一个元素和下一行第一个元素,发现他们的空间只隔了sizeof(int)个位置。
因此打印二维数组里面所有的元素可以这样。
int i;
int* pc=buf[0];
for(i=0;i<12;i++)
printf("%d ",pc[i]);
printf("\n");