C语⾔⼆维数组指针(指向⼆维数组的指针)详解
声明!本⽂转载仅为⽅便学习使⽤!
如有需要,请访问
⼆维数组在概念上是⼆维的,有⾏和列,但在内存中所有的数组元素都是连续排列的,它们之间没有“缝隙”。以下⾯的⼆维数组 a 为例:int a[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};
从概念上理解,a 的分布像⼀个矩阵:
0123
4567
891011
但在内存中,a 的分布是⼀维线性的,整个数组占⽤⼀块连续的内存:
⼆维数组在内存中的存储
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,那么每个⼀维数组的⾸地址如下图所⽰
为了更好的理解指针和⼆维数组的关系,我们先来定义⼀个指向 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 来访问⼆维数组中的每个元素。按照上⾯的定义:
1. p指向数组 a 的开头,也即第 0 ⾏;p+1前进⼀⾏,指向第 1 ⾏。
2. *(p+1)表⽰取地址上的数据,也就是整个第 1 ⾏数据。注意是⼀⾏数据,是多个数据,不是第 1 ⾏中的第 0 个元素,下⾯的运⾏结
果有⼒地证明了这⼀点:
#include<stdio.h>
int main(){
int a[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
3. *(p+1)+1表⽰第 1 ⾏第 1 个元素的地址。如何理解呢?
c语言二维数组表示方法
*(p+1)单独使⽤时表⽰的是第 1 ⾏数据,放在表达式中会被转换为第 1 ⾏数据的⾸地址,也就是第 1 ⾏第 0 个元素的地址,因为使⽤整⾏数据没有实际的含义,编译器遇到这种情况都会转换为指向该⾏第 0 个元素的指针;就像⼀维数组的名字,在定义时或者和 sizeof、& ⼀起使⽤时才表⽰整个数组,出现在表达式中就会被转换为指向数组第 0 个元素的指针。
4. *(*(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>
int main(){
int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
int(*p)[4];
int i,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 个字节的内存。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论