C语言指针进阶阶段学习总结(函数指针、回调、qsort全梳理)
前言
耗时数日完整攻克C语言指针后半段最难板块:二级指针、数组指针、字符指针、函数指针、函数指针数组、回调函数、qsort库排序函数,结合四则计算器实战项目落地知识点,把抽象的指针语法全部转化为可运行代码,做一份完整学习复盘记录。
一、核心知识点逐条复盘
1. 基础指针&字符串关键区分
1. strlen :统计字符串有效字符长度,不计末尾 \0 结束标志
2. sizeof :计算变量/数组占用总内存字节,包含字符串末尾 \0
3. 数组作为函数参数传递时:数组会被隐式转为首元素指针,无法在函数内部计算数组总长度,这是初学高频易错点。
2. 各类指针变量细致区分(重中之重)
1. 字符指针变量 char* ps
存放字符串常量首元素地址,字符串常量存放在只读内存区,不可修改内容;
c
char* ps = "abcdef";
2. 字符数组 char arr[] = "abc";
字符串拷贝到数组栈空间内,内容支持修改。
3. 数组指针变量
专门用来存放整个数组的地址,语法: int (*p)[10] = &arr;
括号绝对不能省略,省略就会变成指针数组,二者完全不同。
4. 指针数组
数组里每一个元素都是指针,常见: char* arr[] (字符串数组)、 int* arr[] (整型指针数组)。
5. 二级指针 int** pp
存放一级指针变量的地址,多用于操作指针数组。
3. 函数指针体系(本次学习核心)
1. 函数指针变量
函数名和 &函数名 等价,都代表函数入口地址;
语法格式: 返回值类型 (*指针名)(参数类型);
示例:
c
// 接收两个int、返回int的函数指针
int (*pf)(int, int) = Add;
2. 函数指针数组
将多个同类型函数的地址存入数组,语法:
c
int (*pfarr[4])(int, int) = {Add, Sub, Mul, Div};
最大用处:替代冗余switch分支语句,依靠下标直接调用对应函数,代码极简、方便扩展,本次四则计算器项目核心骨架。
3. typedef 简化复杂指针类型
用来给繁琐的指针类型重命名,对比 #define 宏单纯文本替换:
- typedef :编译阶段类型重定义,类型安全
- #define :预处理直接文本替换,容易出现边界bug
面对多层嵌套函数指针,typedef可以大幅降低书写难度。
4. 回调函数 & qsort快速排序库函数
1. 回调函数定义:将函数指针作为参数传入另一个函数,外部传入不同逻辑函数,同一个函数内部就可以实现不同功能。
2. qsort 标准库排序函数
C语言stdlib.h自带通用快速排序函数,底层依托回调机制:
自定义比较规则回调函数,就可以对任意类型数据(整型、字符、结构体)完成升序/降序排序,是回调函数最经典的实战场景。
二、实战项目:双版本四则运算计算器
依托函数指针知识点,先后编写两个版本计算器,循序渐进优化代码:
版本1:基础版
- 编写加、减、乘、除4个运算独立函数
- 封装计算函数,接收函数指针参数完成运算
- main函数依靠switch判断用户输入选项,匹配后调用对应运算
- 支持循环菜单、退出程序、非法输入提醒
版本2:函数指针数组优化版(最终定稿)
1. 把四则运算函数地址存入函数指针数组,彻底删除冗长switch语句
2. 用户输入数字1~4,直接用数组下标调取运算函数,代码整洁度大幅提升
3. 完善容错逻辑:输入0退出程序、数字超出范围报错提示
4. 完整手写调试全部流程,吃透指针传递、函数调用底层逻辑
三、学习易错点总结
1. 各类指针书写括号位置极易写错:数组指针、函数指针括号缺一不可;
2. 混淆指针数组与数组指针,是指针阶段最容易踩的坑;
3. 函数指针调用传参顺序颠倒;
4. 除法运算未对除数为0做防护(后续迭代优化补充);
5. qsort回调比较函数返回值逻辑容易记反,影响升降序结果。
四、后续学习计划
1. 完整吃透qsort函数,手写int数组、字符数组两套排序案例;
2. 完善计算器项目:增加除数0判定、连续计算、历史结果查看功能;
3. 整体复盘全部指针知识点,梳理思维导图巩固记忆;
4. 开始预备C语言结构体、文件操作内容,为后续51单片机、STM32嵌入式开发铺垫基础。
收尾感悟
指针是C语言的灵魂,前期晦涩难懂,结合计算器实战一点点拆解之后,终于打通了函数指针、回调思想。这部分内容是嵌入式开发底层必备基础,学好之后后续单片机驱动、硬件代码编写会轻松很多。https://gitcode.com/gcw_RyL6LF93/study-c-languague.git仓库地址
