news 2026/4/26 15:23:05

指针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/4/23 15:51:36

STM32F407最小系统硬件设计与CubeMX工程实践

1. STM32F407最小系统与开发板硬件架构解析 在嵌入式系统工程实践中&#xff0c;硬件平台是所有软件功能落地的物理基础。对于STM32F407这一经典高性能MCU而言&#xff0c;其最小系统设计并非简单的芯片加电源&#xff0c;而是围绕Cortex-M4内核构建的一套完整信号完整性、时钟…

作者头像 李华
网站建设 2026/4/20 13:49:43

Qwen3-ASR-0.6B数据库优化:语音识别结果高效存储

Qwen3-ASR-0.6B数据库优化&#xff1a;语音识别结果高效存储 1. 客服质检场景下的数据洪流困局 上周跟一家做智能客服系统的团队聊了聊&#xff0c;他们刚上线Qwen3-ASR-0.6B模型&#xff0c;识别效果确实让人眼前一亮——方言识别准确率比之前高了近20%&#xff0c;处理5小时…

作者头像 李华
网站建设 2026/4/21 8:30:14

STM32外部中断系统深度解析:EXTI硬件架构与NVIC优先级调度

1. STM32外部中断系统深度解析:从信号路径到优先级调度 在嵌入式系统开发中,中断机制是连接物理世界与软件逻辑的核心桥梁。当一个按键被按下、ADC转换完成、串口数据到达或定时器溢出时,CPU需要立即响应这些异步事件,而非被动轮询。STM32F1系列作为工业级主流MCU,其外部…

作者头像 李华
网站建设 2026/4/23 11:50:10

圣光艺苑AI创作实测:3步生成博物馆级艺术作品

圣光艺苑AI创作实测&#xff1a;3步生成博物馆级艺术作品 1. 走进画室&#xff1a;这不是一个工具&#xff0c;而是一场艺术修行 你有没有试过&#xff0c;在深夜打开一个AI绘图工具&#xff0c;输入“梵高风格的星空教堂”&#xff0c;然后盯着进度条&#xff0c;等它吐出一…

作者头像 李华
网站建设 2026/4/25 6:15:00

告别视频下载难题:哔哩下载姬的高清视频保存新玩法

告别视频下载难题&#xff1a;哔哩下载姬的高清视频保存新玩法 【免费下载链接】downkyi 哔哩下载姬downkyi&#xff0c;哔哩哔哩网站视频下载工具&#xff0c;支持批量下载&#xff0c;支持8K、HDR、杜比视界&#xff0c;提供工具箱&#xff08;音视频提取、去水印等&#xff…

作者头像 李华