指针和二维数组的关系

指针引用多维数组

要了解二维数组首先我们对一维数组需要有基本了解:例

#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;
}

在上述这个例子中我们可以得到几个结论:

  1.   数组名代表数组首元素地址。
  2.      对于 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");
  }

 

posted @ 2015-08-27 20:28  吉吉熊  阅读(237)  评论(0编辑  收藏  举报
.catelog-title {margin-left:0}