news 2026/6/4 23:18:52

指针2(数组名的理解、二级指针、指针数组)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
指针2(数组名的理解、二级指针、指针数组)

文章目录

    • 一、数组名的理解
    • 二、使用指针访问数组
    • 三、一维数组传参的本质
    • 四、二级指针
    • 五、指针数组
    • 六、指针数组模拟二维数组

一、数组名的理解

当我们创建一个数组,想要得到数组首元素地址时,就可以使用&arr[0] ,得到数组首元素地址,除此之外,还可以直接使用数组名,因为数组名其实就等于数组首元素地址

测试:


很显然p1和p2的地址是一模一样的,所以数组名就是数组首元素地址
但需要注意的是,数组名等于数组首元素地址有两个例外:

1.sizeof(数组名),当在sizeof()中单独放数组名的时候,这时,数组名不再表示数组首元素地址,而是表示整个数组,因此这里计算的其实是整个数组的大小,并非数组首元素大小

2.&数组名,这里表示的其实是整个数组,取出的是整个数组的地址;在对这样方式取出来的地址进行±整数操作时,也会有所不同
例如:

可以发现,&arr和&arr[0]在进行+1操作时,&arr+1跳过了40个字节,也就是跳过了一整个数组;&arr[0]+1跳过了4个字节,也就是一个元素

除此之外,在其他地方使用数组名就表示数组首元素地址

二、使用指针访问数组

在之前,我们访问数组都是使用的下标访问操作符[ ],在学习指针后,我们还可以使用指针的方式访问数组,首先,创建一个指针变量p,将数组首元素地址存入p当中,然后再对p进行±整数的操作访问数组所有元素
例如:

通过这个代码,我们可以发现,p和数组名arr貌似是等价的,既然arr能通过[ ]访问数组内的元素,
那么p是不是也应该可以呢?
测试一下:

显然,这是可行的
由此,我们可以得出*(p+i) = arr[ i ];同理,arr[ i ] = *(arr+i)

三、一维数组传参的本质

#include<stdio.h>size_ttest(intarr[]){returnsizeof(arr)/sizeof(arr[0]);}intmain(){intarr[10]={1,2,3,4,5,6,7,8,9,10};size_tsz1=sizeof(arr)/sizeof(arr[0]);size_tsz2=test(arr);printf("sz1 = %zu\n",sz1);printf("sz2 = %zu\n",sz2);}

运行后发现,在x86的环境下时,sz1 = 10,sz2 = 1;在x64的环境下时,sz1 = 10,sz2 = 2,这是什么原因呢?
其实是因为数组名是数组首元素地址,在数组传参的时候,其实传递的是数组名,也就是说本质上数组传参传递的是数组首元素的地址,函数形参的部分理论上应该使用指针变量来接收首元素地址。所以sizeof(arr)计算的其实是一个指针的大小,这也正是为什么在x86和x64的环境下,sz2的结果不一样。
因此,在函数内部是没有办法求数组的元素个数的

总结:一维数组传参,形参可以写成数组的形式,也可以写成指针的形式

四、二级指针

指针变量也是变量,是变量就有地址,想要存放指针变量,就需要使用到二级指针,同样的,二级指针变量也有地址,存储二级指针变量就需要三级指针变量
二级指针的创建方法:

#include<stdio.h>intmain(){inta=10;int*pa=&a;int**ppa=&pa;printf("pa = %p\n",pa);printf("ppa = %p\n",ppa);}

这里的ppa就是二级指针,ppa存放的就是指针变量pa的地址,ppa的类型就是int* 类型
当我们需要访问a的内容的时候,就需要使用两次解引用操作*(*(ppa)),*ppa解引用后就是pa,pa再解引用就指向了a

五、指针数组

指针数组就是存放指针的数组

创建方式:

#include<stdio.h>intmain(){inta=10;intb=20;intc=30;int*parr[]={&a,&b,&c};inti=0;for(i=0;i<3;i++){printf("%d ",*parr[i]);}}

这样就成功创建了一个指针数组,指针数组中的每一个元素都是一个指针,想要访问该指针指向的内容就需要进行解引用操作

六、指针数组模拟二维数组

#include<stdio.h>intmain(){intarr1[5]={1,3,5,7,9};intarr2[5]={2,4,6,8,10};intarr3[5]={1,2,3,4,5};int*parr[]={arr1,arr2,arr3};for(inti=0;i<3;i++){for(intj=0;j<5;j++){printf("%d ",parr[i][j]);}printf("\n");}}

parr[ i ]就是访问parr数组的元素,parr[ i ]找到的数组元素指向了一维数组,parr[ i ][ j ]就是访问指向的一维数组当中的元素
需要注意的是,上面的代码只是模拟出二维数组的效果,并不是真正意义上的二维数组,因为每一行并非是连续的


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/30 15:01:23

STM32CubeMX项目结构深度解析:Core/Drivers/Middleware/Startup四大分区

4.2 CubeMX生成项目的文件组成&#xff1a;深度解析STM32工程结构与代码组织逻辑在嵌入式开发实践中&#xff0c;一个清晰、可维护、可扩展的项目结构是工程稳定性的基石。STM32CubeMX作为ST官方提供的图形化配置与代码生成工具&#xff0c;其核心价值不仅在于简化外设初始化流…

作者头像 李华
网站建设 2026/5/15 20:37:17

Swin2SR与YOLOv8结合:高清化处理提升目标检测精度

Swin2SR与YOLOv8结合&#xff1a;高清化处理提升目标检测精度 1. 为什么模糊图像会拖累目标检测效果 在实际应用中&#xff0c;我们经常遇到这样的问题&#xff1a;监控摄像头拍到的画面模糊不清&#xff0c;无人机航拍的远距离目标细节丢失&#xff0c;或者低光照环境下拍摄…

作者头像 李华
网站建设 2026/5/21 23:07:24

STM32通用定时器原理与HAL库实战配置

1. 通用定时器的核心定位与系统级意义在STM32F4系列微控制器的外设矩阵中&#xff0c;通用定时器&#xff08;General-Purpose Timer&#xff09;绝非一个孤立的功能模块&#xff0c;而是贯穿整个系统时序控制、事件同步与实时响应能力的中枢神经。它既承担着最基础的毫秒级延时…

作者头像 李华
网站建设 2026/6/4 10:57:08

STM32F407硬件级RTC入侵检测与时间戳捕获实验

11. RTC入侵检测与时间戳实验&#xff1a;基于STM32F407的硬件级安全事件捕获机制 在嵌入式系统中&#xff0c;对物理访问异常的实时感知与精确记录&#xff0c;是工业控制、智能电表、医疗设备及金融终端等高可靠性场景的核心安全需求。RTC&#xff08;Real-Time Clock&#x…

作者头像 李华
网站建设 2026/5/28 1:18:21

Qwen-Image-Edit-F2P模型微调:使用Dify平台实现个性化风格迁移

Qwen-Image-Edit-F2P模型微调&#xff1a;使用Dify平台实现个性化风格迁移 你有没有想过&#xff0c;把自己的照片变成一幅油画、一张动漫海报&#xff0c;或者一种特定的艺术风格&#xff1f;以前这需要专业的设计师和复杂的软件&#xff0c;但现在&#xff0c;借助AI的力量&…

作者头像 李华
网站建设 2026/5/20 17:17:31

能力中心 (Agent SkillCenter):开启AI技能管理新时代

&#x1f31f; 什么是能力中心&#xff1f; 能力中心 (Agent SkillCenter) 是一个革命性的AI技能管理平台&#xff0c;为企业和个人用户提供全方位的技能生命周期管理解决方案。它不仅是一个技能市场&#xff0c;更是一个去中心化的AI能力生态系统。 &#x1f3af; 核心功能亮…

作者头像 李华