指针和二维数组的关系
指针引用多维数组
要了解二维数组首先我们对一维数组需要有基本了解:例
#include <stdio.h> int main(void) { int b[6] ={1,2,3,4,5,6}; printf("&a[0]==%p\n",&b[0]); printf("b==%p\n",b); printf("b+1==%p\n",b+1); printf("%d\n",b[0]); char str[6] = {'H','e','l','l','e'}; printf("&str[0]==%p\n",&str[0]); printf("str==%p\n",str); printf("str+1==%p\n",str+1); printf("%c\n",str[0]); return 0; }
在上述这个例子中我们可以得到几个结论:
- 数组名代表数组首元素地址。
- 对于 b+1,str+1 == 加数 * 类型的占用空间 + 首地址;例如 b=2000, b+1 = 1*4 +2000;
知道这个基本点后我们来列举二维数字
int a[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}};
二维数组 | |||||
a[0] | == | 1 | 3 | 5 | 7 |
a[1] | == | 9 | 11 | 13 | 15 |
a[2] | == | 17 | 19 | 21 | 23 |
OK,二维数组在我们眼中,相当于三个一维数组组成;a代表着 二维数组的首地址。 而在二维数组中需要我们特别注意的是 a+1 指向其实是a[1]的地址.
我们在例子中设置的是 “INT” 类型的,在32位 vs中 每个int型代表着 4个字节。 假设:“a”的首地址是2000,那么“a+1”的地址就是2000+4*4 = 2016;
在二维数组中有些难以理解的问题我们通过代码进行一些演示:
#include <stdio.h> int main(void) { int a[3][4] = { {1,3,5,7}, {9,11,13,15}, {17,19,21,23} }; printf("a==%p\n",a); printf("*a==%p\n",*a); printf("a[0]==%p\n",a[0]); printf("&a[0]==%p\n",&a[0]); printf("&a[0][0]==%p\n",&a[0][0]); }
好吧我们惊奇的发现,这好不科学,但这是基本事实。 我们在上边说a[0].a[1],a[2] 是数组明,在c语言中数组名代表了数组的首元素 也就意味a[0],a[1],a[2]数值就是地址。 那如果我们要表达 “a[0][1]”的地址怎么办? ok, 由一维数组的特性我们可以知道,“加数 * 类型的占用空间 + 首地址” 在这里同样受用,所以我们得到了一个 “a[0][1]” = a[0]+1 = *(a+0)+1 (ps: 这里都是地址哦) 不是数值。
知道这些还不够。还需要继续深入理解这个问题。
int a[3][4] = { {1,3,5,7}, {9,11,13,15}, {17,19,21,23} }; printf("a[0]==%p\n", a[0]); printf("*a==%p\n",*a); printf("a[0]+10==%p\n", a[0]+10); printf("*a+10==%p\n",*a+10); printf("*(a+2)+2 = %p\n",*(a+2)+2); printf("a[2][2] ==%p\n",&a[2][2]); }
int main(void) { int a[3][4] = { {1,3,5,7}, {9,11,13,15}, {17,19,21,23} }; int (*p)[4],row,col; printf("please enter row and column"); scanf("%d,%d",&row,&col); printf("a[%d][%d]=%d\n",row,col,*(*(a+row)+col)); return 0; }
我们可以看到 二维数组是可以当成以为数组处理的 int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; 我们举例子说明这个问题;三名同学,每个同学有四们课程,我们现在求全部课程的平均分数。
#include <stdio.h> int main() { void ave(float *p,int n); float scores[3][4]={{67,69,75,53},{55,65,73,85},{42,62,82,87}}; ave(*scores,12); return 0; } void ave(float *p,int n) { float *end; float sum=0,aver; end=p+n-1; // *scores + n -1 相当于一维数组的处理方式{67,69,75,53,55,65,73,85,42,62,82,87} 已有举例
for(;p<=end;p++) sum=sum+(*p); aver=sum/n; printf("average=%5.2f\n",aver); }
我们在上述例子中用了带参数的函数: ave(*scores,n); 这里的*scores 就是 a[0][0]的地址值。
下边谈一个搜索某单一学好的例子 采用的是
#include <stdio.h> int main() {void average(float *p,int n); void search(float (*p)[4],int n); float score[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}}; average(*score,12); search(score,2); return 0; } void search(float (*p)[4],int n) {int i; printf("The score of No.%d are:\n",n); for(i=0;i<4;i++) printf("%5.2f ",*(*(p+n)+i)); printf("\n"); }