下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

二维数组和指针的关系

作者:课课家教育     来源: http://www.kokojia.com点击数:2475发布时间: 2019-03-20 16:19:27

标签: 编程语言C语言二维数组.指针

大神带你学编程,欢迎选课

  在数组的学习中我们了解了二维数组的相关概念和作用,在实际的编写过程中往往会用到二维数组和指针结合使用的情况,那么两种的关系到底是什么呢?下面课课家小编就为大家简单介绍二维数组和指针两者之间的关系。

二维数组和指针的关系_编程语言_C语言_二维数组_指针_课课家教育

  在C语言中,二维数组在概念上是二维的,有行和列,但在内存中所有的数组元素都是连续排列的,它们之间没有“缝隙”。下面小编以二维数组a为大家举例:

  inta[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};

  从概念上理解,a的分布像一个矩阵,具体如下图所示:

  图1.1

 

  但在内存中,a的分布是一维线性的,整个数组占用一块连续的内存,具体如下图所示:

图2

  C语言中的二维数组是按行排列的,也就是先存放a[0]行,再存放a[1]行,最后存放a[2]行;每行中的4个元素也是依次存放。数组a为int类型,每个元素占用4个字节,整个数组共占用4×(3×4)=48个字节。C语言允许把一个二维数组分解成多个一维数组来处理。对于数组a,它可以分解成三个一维数组,也就是a[0]、a[1]、a[2]。每一个一维数组又包含了4个元素,比如a[0]包含a[0][0]、a[0][1]、a[0][2]、a[0][3]。下面小编假设数组a中第0个元素的地址为1000,那么每个一维数组的首地址如下图所示:

图3

  为了更好的理解指针和二维数组的关系,小编先给大家来定义一个指向a的指针变量p:int(*p)[4]=a;。括号中的*表明p是一个指针,它指向一个数组,数组的类型为int[4],这正是a所包含的每个一维数组的类型。[]的优先级高于*()是必须要加的,如果赤裸裸地写作int*p[4],那么应该理解为int*(p[4]),p就成了一个指针数组,而不是二维数组指针。

  在我们对指针进行加法(减法)运算时,它前进(后退)的步长与它指向的数据类型有关,p指向的数据类型是int[4],那么p+1就前进4×4=16个字节,p-1就后退16个字节,这正好是数组a所包含的每个一维数组的长度。也就是说p+1会使得指针指向二维数组的下一行,p-1会使得指针指向数组的上一行。数组名a在表达式中也会被转换为和p等价的指针。下面我们使用指针p来访问二维数组中的每个元素,按照上面的定义:

  ①p指向数组a的开头,也即第0行;p+1前进一行,指向第1行。

  ②*(p+1)表示取地址上的数据,也就是整个第1行数据。注意是一行数据,是多个数据,不是第1行中的第0个元素,下面的输出结果证明了这一点:

  #include<stdio.h>

  intmain(){

  inta[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};

  int(*p)[4]=a;

  printf("%d\\n",sizeof(*(p+1)));

  return0;

  }

  输出结果:

  16

  ③*(p+1)+1表示第1行第1个元素的地址。*(p+1)单独使用时表示的是第1行数据,放在表达式中会被转换为第1行数据的首地址,也就是第1行第0个元素的地址,因为使用整行数据没有实际的含义,编译器遇到这种情况都会转换为指向该行第0个元素的指针;就像一维数组的名字,在定义时或者和sizeof、&一起使用时才表示整个数组,出现在表达式中就会被转换为指向数组第0个元素的指针。

  ④*(*(p+1)+1)表示第1行第1个元素的值。很明显,增加一个*表示取地址上的数据。根据上面的结论,我们可以简单导出以下的等价关系:

  a+i==p+i

  a[i]==p[i]==*(a+i)==*(p+i)

  a[i][j]==p[i][j]==*(a[i]+j)==*(p[i]+j)==*(*(a+i)+j)==*(*(p+i)+j)

  接下来小编使用指针遍历二维数组来给大家举个例子。

  #include<stdio.h>

  intmain(){

  inta[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};

  int(*p)[4];

  inti,j;

  p=a;

  for(i=0;i<3;i++){

  for(j=0;j<4;j++)printf("%2d",*(*(p+i)+j));

  printf("\\n");

  }

  return0;

  }

  输出结果:

  0123

  4567

  891011

  ◎指针数组和二维数组指针的区别

  指针数组和二维数组指针在定义时非常相似,只是括号的位置不同:

  int*(p1[5]);//指针数组,可以去掉括号直接写作int*p1[5];

  int(*p2)[5];//二维数组指针,不能去掉括号

  指针数组和二维数组指针有着本质上的区别:指针数组是一个数组,只是每个元素保存的都是指针,以上面的p1为例,在32位环境下它占用4×5=20个字节的内存。二维数组指针是一个指针,它指向一个二维数组,以上面的p2为例,它占用4个字节的内存。大家在编写时请务必记住这一点。

  本次二维数组和指针的关系的讲解教程到此暂告一段落,如果以后有什么内容继续补充或者修改的话小编会在此进行补充或者修改,同时也欢迎大家对本次的讲解提出自己的建议和补充。最后小编希望本次的讲解能够对大家学习C语言起到一定的帮助作用!

赞(0)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程