当前位置:网站首页>指针数组和数组指针
指针数组和数组指针
2022-07-04 03:47:00 【研究僧-彬彬】
指针数组和数组指针
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;
数组指针实质上是一个指针,指向数组,与指针数组最大的区别在于星号与数组名用括号括起来了。
注意到上面的类型是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就前进34=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)。
边栏推荐
- Zigzag scan
- MySQL maxscale realizes read-write separation
- JDBC advanced
- 【华为云IoT】读书笔记之《万物互联:物联网核心技术与安全》第3章(上)
- Is it really so difficult to learn redis? Today, a fan will share his personal learning materials!
- “软硬皆施”,助力建成新型云计算数据中心
- 02 ls 命令的具体实现
- Object oriented -- encapsulation, inheritance, polymorphism
- 【CSRF-01】跨站请求伪造漏洞基础原理及攻防
- Huawei cloud Kunpeng engineer training (Guangxi University)
猜你喜欢

Brief explanation of depth first search (with basic questions)

National standard gb28181 protocol platform easygbs fails to start after replacing MySQL database. How to deal with it?

LNK2038 检测到“RuntimeLibrary”的不匹配项: 值“MD_DynamicRelease”不匹配值“MDd_DynamicDebug”(main.obj 中)

1289_ Implementation analysis of vtask suspend() interface in FreeRTOS

Katalon中控件的参数化

Wechat official account web page authorization

The maximum expiration time of client secret in azure ad application registration is modified to 2 years

ctf-pikachu-CSRF

还原窗口位置的微妙之处

深度优先搜索简要讲解(附带基础题)
随机推荐
Third party login initial version
Introduction to asynchronous task capability of function calculation - task trigger de duplication
10 reasons for not choosing to use free virtual hosts
Objective-C member variable permissions
Penetration practice - sqlserver empowerment
Storage of MySQL database
CesiumJS 2022^ 源码解读[0] - 文章目录与源码工程结构
Smart subway | cloud computing injects wisdom into urban subway transportation
渗透实战-SQLServer提权
Illustrated network: what is the hot backup router protocol HSRP?
LNK2038 检测到“RuntimeLibrary”的不匹配项: 值“MD_DynamicRelease”不匹配值“MDd_DynamicDebug”(main.obj 中)
【webrtc】m98 ninja 构建和编译指令
选择排序与冒泡排序模板
Brief explanation of depth first search (with basic questions)
functools下的reduce函数
[paddleseg source code reading] paddleseg calculation dice
Rhcsa-- day one
laravel admin里百度编辑器自定义路径和文件名
Typical applications of minimum spanning tree
[PaddleSeg 源码阅读] PaddleSeg Transform 的 Normalize操作