当前位置:首页 > 学习资源 > 讲师博文 > 数组指针与指针数组有什么区别?

数组指针与指针数组有什么区别? 时间:2026-09-16      来源:华清远见

前言

在嵌入式C语言开发中,指针数组和数组指针是最容易写出隐性Bug的两个知识点。不同于上层软件开发,嵌入式开发对内存布局、地址偏移、参数传参、栈内存占用极度敏感,很多看似能正常编译的代码,实则暗藏越界访问、内存踩踏、函数传参失效、硬件数据读取异常等问题。

很多小白只会死记硬背口诀:“指针数组是数组,数组指针是指针”,但完全不懂内存分布差异、寻址逻辑、传参本质、适用场景。在实际项目中:串口协议解析、多维数据存储、字符串批量管理、二维数组传参、外设参数配置、固件字典映射,几乎处处用到这两个语法。

更关键的是:这两个知识点是嵌入式笔试、面试、机试的高频必考重难点,也是区分“会写代码”和“懂底层原理”的核心分水岭。

本文摒弃空洞概念背诵,完全贴合嵌入式实际开发场景,从定义本质、内存原理、代码实操、经典坑点、编译报错、工程选型、面试考点全方位拆解,带你彻底吃透二者区别,杜绝项目隐性Bug。

一、先定基调:一句话区分核心本质

在深入原理前,先牢记二者的本质属性,所有差异、用法、坑点全部源于属性不同:

•指针数组:本质是【数组】。数组里面存储的元素全部是指针变量,核心用途:批量管理地址、批量存储字符串、指针集合。

•数组指针:本质是【指针】。专门指向一整行数组/二维数组行对象的指针,核心用途:二维数组传参、数组地址偏移、批量操作数组行数据。

简单口诀(理解后记忆):看后缀定本体,看前缀定类型。数组本体存指针=指针数组;指针本体指向数组=数组指针。

二、语法定义与底层内存原理

2.1 指针数组:char *arr[]

2.1.1 语法与本质

定义格式:数据类型 *数组名[数组长度]

示例:char *str_arr[5];

优先级关键:[] 优先级高于 *,变量先和 [] 结合形成数组,再和 * 结合,代表数组每个元素是指针。

本质:开辟一段连续的栈/全局内存空间,空间内存储5个char*类型的指针,每个指针独立指向不同的字符串地址或内存地址。

2.1.2 内存分布特点(嵌入式重点)

1. 数组本体内存连续,所有指针变量地址相邻;

2. 指针指向的字符串内存不连续,每个指针可指向任意地址,无内存对齐约束;

3. 适合存储长度不一致的字符串,极致节省内存,嵌入式项目中广泛用于指令集、设备名称、错误码提示。

2.1.3 实战代码示例(可直接编译运行)

2.1.4 工程优缺点与适用场景

优点:支持不等长数据存储、内存利用率高、定义简单、遍历方便,无需冗余占位;

缺点:指针分散寻址,不适合批量连续读写硬件内存;无法直接作为二维数组使用;

嵌入式场景:串口指令解析、错误信息数组、设备参数名称、固件菜单字符串集合。

2.2 数组指针:char (*p)[N]

2.2.1 语法与本质

定义格式:数据类型 (*指针名)[数组长度]

示例:char (*p)[5];

优先级关键:() 改变优先级,p先和*结合成为指针,再和[]结合,代表该指针指向一个「包含5个元素的数组」。

本质:一个行指针,专门指向固定长度的一维数组,核心用于操作二维数组的整行数据。

2.2.2 内存分布特点

1. 数组指针本身只占4字节(32位单片机)/8字节(64位),和普通指针大小一致;

2. 指针步进单位为一整行数组长度,p+1 直接跳过一整行所有元素,而非单个元素;

3. 必须指向长度固定、内存连续的数组,适配二维数组连续内存特性。

2.2.3 实战代码示例(二维数组传参核心用法)

2.2.4 工程优缺点与适用场景

优点:完美适配二维数组传参、指针步进规整、内存连续可控、适合批量读写整块数据;

缺点:列长度必须固定,灵活性差,无法适配不等长数据;

嵌入式场景:传感器多维数据存储、缓冲区批量读写、Flash分区数据操作、矩阵参数运算。

三、嵌入式高频致命坑点(90%新手踩坑)

3.1 坑点1:混淆定义语法,编译不报错但运行异常

错误写法:char *p[3] 当成数组指针使用,试图接收二维数组;

问题根源:这是指针数组,是数组不是指针,无法指向二维数组行地址,传参直接类型不匹配,出现内存乱访问、数据错乱。

解决方案:二维数组传参必须用 char (*p)[列数] 数组指针。

3.2 坑点2:指针数组存储字符串,误修改只读内存

嵌入式中 char *str[] = {"abc"} 字符串存储在Flash只读段,并非栈内存;

新手尝试修改 str[0][0] = 'x',直接触发内存访问异常、单片机死机。

解决方案:需要可修改字符串时,使用二维数组 char str[][10] 存储,分配栈/全局可读写内存。

3.3 坑点3:数组指针步进理解错误,导致数据偏移越界

普通指针 p+1 跳过1个字节/1个元素;数组指针 p+1 跳过一整行;

新手误用数组指针做单元素遍历,直接跳过大量数据,造成读取数据缺失、数组越界。

3.4 坑点4:sizeof计算混淆,导致数组长度计算错误

指针数组:sizeof(arr) 获取整个数组总大小,可正常计算元素个数;

数组指针:sizeof(p) 永远是指针大小(4/8字节),无法计算数组长度,强行计算会出现参数错乱。

四、核心区别全方位对比(工程对照表)

五、嵌入式工程选型标准(直接照抄落地)

1. 需要存储大量长短不一的字符串、指令、提示文本 → 优先用【指针数组】,节省内存、定义简洁;

2.需要函数传递二维数组、批量操作整行数据 → 必须用【数组指针】,唯一合规传参方式;

3. 数据需要频繁修改、读写 → 拒绝指针数组(指向只读段),改用二维数组;

4. 硬件缓冲区、连续内存数据解析 → 用数组指针规整遍历,避免地址错乱。

六、总结

指针数组与数组指针的混淆,本质不是语法难,而是只记表象、不究底层内存原理。对于嵌入式开发而言,语法只是表象,内存布局、寻址方式、堆栈占用、硬件内存映射才是核心。

简单复盘核心逻辑:指针数组是存指针的容器,主打灵活存储、批量管理离散数据;数组指针是管数组的地址工具,主打规整寻址、批量操作连续内存。

在单片机、Linux嵌入式开发中,杜绝死记硬背口诀,真正理解二者的内存差异和适用场景,才能规避字符串修改死机、数组越界、传参失效、数据错乱等隐性工程Bug,写出稳定、高效、贴合硬件底层的C语言代码。

上一篇:FreeRTOS任务优先级应该怎样设置?嵌入式工程实战最全指南

下一篇:Python浅拷贝与深拷贝有什么不同?

戳我查看嵌入式每月就业风云榜

点我了解华清远见高校学霸学习秘籍

猜你关心企业是如何评价华清学员的

干货分享
相关新闻
前台专线:010-82525158 企业培训洽谈专线:010-82525379 院校合作洽谈专线:010-82525379 Copyright © 2004-2026 北京华清远见科技发展有限公司 版权所有 ,京ICP备16055225号-5京公海网安备11010802025203号

回到顶部