
C语言进阶void指针、二级指针、指针数组与数组指针、二维数组传参全解前言今天系统学习C语言高阶指针知识点涵盖万能void指针、二级指针、const修饰指针、指针数组与数组指针区分、二维数组指针底层逻辑与函数传参这部分是C语言笔试、开发核心难点整理完整知识点、易错点与实操逻辑方便复习查阅。一、void万能指针1. 核心概念void指针是无固定类型的通用指针可以接收任意数据类型变量的内存地址作为通用地址容器。64位系统所有指针均占8字节void指针也不例外但编译器不知道它指向的数据占多少字节因此禁止直接解引用*。2. 转换规则任意类型int* / char* / float*可以隐式自动转为void*使用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关键字代表只读修饰指针时分两种修饰对象修饰指针指向的数据、修饰指针变量本身。const int *p/int const *pconst修饰*p指针p可以修改指向但不能通过p修改指向空间的值int *const pconst修饰指针p本身定义时必须初始化p的指向永久不能修改但可修改*pconst int *const p双重限制指针不可改指向指向内容也不可修改完全只读。四、指针数组 VS 数组指针面试高频区分点1. 指针数组int *a[5]本质数组数组内每一个元素都是int*一级指针内存大小64位系统 5 * 8 40字节核心用途存储一组字符串替代笨重的二维字符数组示例constchar*month[]{January,February,March};2. 数组指针int (*p)[5]本质指针仅占8字节专门指向包含5个int的完整一维数组运算特性p一次性跳过5个int20字节步长为整个数组大小区分技巧运算符优先级[] *不加括号是数组括号包裹(*p)才是指针。五、二维数组底层与指针访问1. 二维数组存储规则int a[2][3]在内存中逐行连续存储不存在行间空隙。2. 各地址层级含义a数组指针指向第0整行类型int(*)[3]a跳过一整行3个inta[0]/*a普通int*指针指向第0行第0个元素a[0][0]第一个元素的原始地址。3. 元素等价访问方式5种完全等效// 访问第m行第n列a[m][n]*(a[m]n)*(*(am)n)*(pm*3n)// p为int*类型*(*(qm)n)// q为数组指针int(*)[3]六、二维数组函数传参标准写法硬性规则形参必须声明列的固定长度行数可省略底层接收依赖数组指针类型// 两种等价标准写法intgetMax(int(*arr)[3],introw);intgetMax(intarr[][3],introw);错误写法int fun(int arr[2][])编译器无法计算行偏移直接编译报错。七、今日高频易错点汇总void指针直接*解引用编译报错缺少类型宽度必须强制转换分不清int *a[5]与int (*a)[5]括号是区分数组/指针的关键const指针记忆混淆*左侧const限制内容变量名前const限制指针指向滥用二级指针仅修改普通变量用一级指针只有修改外部指针变量才用二级指针二维数组传参遗漏列数导致编译失败数组指针运算步长理解错误int (*p)[5]自增一次跳过5个int未初始化void指针、二级指针直接取值触发程序段错误崩溃混淆一维数组a首元素指针和a整个数组指针二者步长天差地别。