指针数组和数组指针

指针数组和数组指针

1.指针数组
int arr[5] = {0, 1, 2, 3, 4};
int *ptrArr[5] = {&arr[0], &arr[1], &arr[2], &arr[3], &arr[4] };
//另一种表示方式int* ptrArr[5] = {&arr[0], &arr[1], &arr[2], &arr[3], &arr[4] };
cout<<*(ptrArr[3])<<endl;	//输出元素3

上图所示是指针数组,实质上是一个数组,里面存在5个元素,每个元素都是一个指针。这个*号靠在int旁边,或是靠在数组名旁边都不影响它的性质。
在这里插入图片描述
可以看到arr数组所在的内存地址为0x00cff7e8,里面存在5个元素,一个元素的大小为4字节。
在这里插入图片描述
看一下指针数组,可以看到里面存着5个指针,这是因为初始化的时候我们将每个指针都指向而一个元素。0号元素的指针为0x00cff7e8,刚好就是0的位置,以此类推。

cout<<*(ptrArr[3])<<endl;	//输出元素3

先解析ptrArr[3],代表数组里面的第4个元素,也就是指针0x00cff7f4,*解引用对应的值就是元素3。

2.数组指针
    int arr[5] = { 0,1,2,3,4};
    int (*arrPtr)[5] = &arr;
    sizeof(arrPtr);		//值为4

数组指针实质上是一个指针,指向数组,与指针数组最大的区别在于星号与数组名用括号括起来了。数组指针本质上也是指针,指针大小一般为4字节。
在这里插入图片描述
注意到上面的类型是int*[5],这里的类型是int[5]*;

cout<<(*arrPtr)[3]<<endl;	//输出元素3

arrPtr实质上是指向数组的指针,通过解引用获得数组,(*arrPtr)[3]就等于arr[3]。

3.指向二维数组的指针

二维数组内存分布如下所示。
假设数组 a 中第 0 个元素的地址为 1000,那么每个一维数组的首地址如下图所示:
在这里插入图片描述

接下来看看再二维数组中数组指针的应用。这是一道牛客网的选择题,答案是10, 20, 30。
在这里插入图片描述
从声明来看int (*p)[3]带着括号,把星号和数组名括起来了,代表这是个数组指针,指向一个3元素的数组。
在这里插入图片描述
在内存分布可以看到,n代表的是一个2*3的数组,而p的声明是指向一个3元素的数组,所以p实质上就是指向了二维数组的第一行。从上面的值也能看出,p=n[0],均是0x00affea0{10,20,30}。

第一个p[0][0]就是等于n[0][0],也就是元素10;

第二个*(p[0] + 1),这里注意p[0]实际上就是n[0],n[0]存储的是第一行的首地址,也就是n[0][0]这个地址,通过+1进行了地址偏移,实质上偏移的是4个字节(int),就变成了n[0][1]这个地址,通过解引用取值20。

第三个(*p)[2],p存的就是n[0],所以(p)[2]等价于n[0][2],所以结果为30。
在这里插入图片描述
拓展一下。p指向的是3元素的数组,即int[3],那么p+1就前进3
4=12字节,也就是二维数组中一行的长度,即p+1会使得指针指向下一行。得出以下等价结论(from C语言中文网):

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)

举例,(p+1)指的是第1行数据,因为使用整行数据没有实际意义,编译器遇到这种情况都会转换为指向该行第0个元素的指针;在下面可以看到,第一行的n[1]的首地址就是0000bafbd8。所以对于一行数据解引用是得到首个元素的地址。
在这里插入图片描述在这里插入图片描述
((p+1)+1)表示第 1 行第 1 个元素的值。这是一个数据,所以解引用就可以获得那个数据。另外一种方式就是,
(p[1]+1)。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值