嵌入式学习13
2026/8/4 4:46:41 网站建设 项目流程

C语言进阶:void指针、二级指针、指针数组与数组指针、二维数组传参全解

前言

今天系统学习C语言高阶指针知识点,涵盖万能void指针、二级指针、const修饰指针、指针数组与数组指针区分、二维数组指针底层逻辑与函数传参,这部分是C语言笔试、开发核心难点,整理完整知识点、易错点与实操逻辑,方便复习查阅。

一、void万能指针

1. 核心概念

void指针是无固定类型的通用指针,可以接收任意数据类型变量的内存地址,作为通用地址容器。
64位系统所有指针均占8字节,void指针也不例外,但编译器不知道它指向的数据占多少字节,因此禁止直接解引用*

2. 转换规则
  1. 任意类型int* / char* / float*可以隐式自动转为void*
  2. 使用void指针取值、运算时,必须强制转换为原数据类型指针。
3. 实操示例

直接操作指定物理内存地址赋值:

// 将0x12345678地址强制转为int*,赋值0x11223344*((int*)((void*)0x12345678))=0x11223344;
4. 典型用途
  • 封装通用工具函数,兼容多种数据类型入参;
  • 内存操作函数memcpy/memset底层全部使用void*实现通用逻辑。

二、二级指针 int** 详解

1. 定义与含义

普通变量int a→ 一级指针int* p = &a(存变量地址)
一级指针int* p→ 二级指针int** q = &p(存一级指针变量的地址)

多层取值关系:

  • q:一级指针变量p的地址
  • *q:等价p,普通变量a的地址
  • **q:等价*p,变量a存储的真实数值
2. 唯一核心使用场景

当我们需要在函数内部修改函数外部定义的一级指针变量时,必须传递二级指针。
普通值传递、一级地址传递只能修改原变量内容,无法修改指针本身的指向。

3. 适用拓展

字符串指针数组做函数参数时,必须搭配二级指针接收。

三、const修饰指针四种写法(必背)

const关键字代表只读,修饰指针时分两种修饰对象:修饰指针指向的数据、修饰指针变量本身。

  1. const int *p/int const *p
    const修饰*p,指针p可以修改指向,但不能通过p修改指向空间的值;
  2. int *const p
    const修饰指针p本身,定义时必须初始化,p的指向永久不能修改,但可修改*p
  3. const int *const p
    双重限制:指针不可改指向,指向内容也不可修改,完全只读。

四、指针数组 VS 数组指针(面试高频区分点)

1. 指针数组int *a[5]
  1. 本质:数组,数组内每一个元素都是int*一级指针;
  2. 内存大小:64位系统 5 * 8 = 40字节;
  3. 核心用途:存储一组字符串,替代笨重的二维字符数组;
  4. 示例:
constchar*month[]={"January","February","March"};
2. 数组指针int (*p)[5]
  1. 本质:指针,仅占8字节;专门指向包含5个int的完整一维数组
  2. 运算特性:p++一次性跳过5个int(20字节),步长为整个数组大小;
  3. 区分技巧:运算符优先级[] > *,不加括号是数组,括号包裹(*p)才是指针。

五、二维数组底层与指针访问

1. 二维数组存储规则

int a[2][3]在内存中逐行连续存储,不存在行间空隙。

2. 各地址层级含义
  1. a:数组指针,指向第0整行,类型int(*)[3],a++跳过一整行3个int;
  2. a[0]/*a:普通int*指针,指向第0行第0个元素;
  3. &a[0][0]:第一个元素的原始地址。
3. 元素等价访问方式(5种完全等效)
// 访问第m行第n列a[m][n]*(a[m]+n)*(*(a+m)+n)*(p+m*3+n)// p为int*类型*(*(q+m)+n)// q为数组指针int(*)[3]

六、二维数组函数传参标准写法

  1. 硬性规则:形参必须声明列的固定长度,行数可省略;
  2. 底层接收依赖数组指针类型:
// 两种等价标准写法intgetMax(int(*arr)[3],introw);intgetMax(intarr[][3],introw);
  1. 错误写法:int fun(int arr[2][]),编译器无法计算行偏移,直接编译报错。

七、今日高频易错点汇总

  1. void指针直接*解引用编译报错,缺少类型宽度,必须强制转换;
  2. 分不清int *a[5]int (*a)[5],括号是区分数组/指针的关键;
  3. const指针记忆混淆:*左侧const限制内容,变量名前const限制指针指向;
  4. 滥用二级指针:仅修改普通变量用一级指针,只有修改外部指针变量才用二级指针;
  5. 二维数组传参遗漏列数,导致编译失败;
  6. 数组指针运算步长理解错误,int (*p)[5]自增一次跳过5个int;
  7. 未初始化void指针、二级指针直接取值,触发程序段错误崩溃;
  8. 混淆一维数组a(首元素指针)和&a(整个数组指针),二者步长天差地别。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询