当前位置: 首页 > news >正文

C语言-指针函数和函数指针

在C语言中,"指针函数"和"函数指针"是容易混淆但完全不同的概念。以下是详细的技术解析:


一、指针函数(返回指针的函数)
定义:返回指针类型的函数
声明格式:返回值类型* 函数名(参数列表)
作用:用于返回内存地址(指针),常用于动态内存分配和数据结构操作

// 返回整型指针的函数
int* create_int_array(int size) {int *arr = (int*)malloc(size * sizeof(int));return arr;  // 返回动态分配的数组首地址
}// 返回字符串指针的函数
char* get_greeting() {return "Hello, World!";  // 返回字符串常量地址
}

典型应用场景:

  1. 工厂模式创建对象
  2. 内存分配函数(如malloc)
  3. 链表/树节点创建函数

注意事项:

// 错误示例:返回局部变量地址
int* dangerous_func() {int local = 100;return &local;  // 局部变量在函数结束后被销毁,返回的指针失效
}

二、函数指针(指向函数的指针)
定义:指向函数入口地址的指针变量
声明格式:返回值类型 (*指针名)(参数列表)
作用:实现回调机制、函数动态调用、策略模式等高级功能

// 声明函数指针类型
typedef int (*MathFunc)(int, int);// 函数指针的使用示例
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }int main() {MathFunc operation = add;printf("3+5=%d\n", operation(3,5));  // 输出8operation = sub;printf("8-3=%d\n", operation(8,3));  // 输出5return 0;
}

典型应用场景:

  1. 事件处理回调(如GUI编程)
  2. 函数表驱动开发(如状态机)
  3. 动态库函数调用(dlopen/dlsym)
  4. 排序算法中的比较函数(qsort)

复杂声明解析:

// 解读:signal是函数,参数int和void(*)(int),返回void(*)(int)
void (*signal(int sig, void (*handler)(int)))(int);// 使用typedef简化
typedef void (*SigHandler)(int);
SigHandler signal(int sig, SigHandler handler);

三、对比表格

特征指针函数函数指针
本质返回指针的函数指向函数的指针变量
声明重点int* func() 星号在返回值位置int (*func_ptr)() 星号在变量名旁
内存占用函数代码段指针变量(通常4/8字节)
典型用途资源创建/获取地址动态调用/回调机制
操作权限定义函数逻辑仅能调用指向的函数
赋值方式函数返回值自动赋值需显式赋值函数地址

四、高级用法示例

  1. 函数指针数组(命令模式)
void start() { printf("Starting...\n"); }
void stop() { printf("Stopping...\n"); }
void reboot() { printf("Rebooting...\n"); }int main() {void (*commands[])() = {start, stop, reboot};int choice;printf("Enter command (0-start, 1-stop, 2-reboot): ");scanf("%d", &choice);if(choice >=0 && choice <=2) {commands[choice]();  // 动态调用}return 0;
}
  1. 结合结构体(策略模式)
typedef struct {float (*calc)(float, float);  // 计算策略char symbol;                  // 运算符
} Operation;float add(float a, float b) { return a + b; }
float multiply(float a, float b) { return a * b; }int main() {Operation ops[] = {{add, '+'},{multiply, '*'}};for(int i=0; i<2; i++) {float res = ops[i].calc(3.5, 2);printf("3.5 %c 2 = %.1f\n", ops[i].symbol, res);}return 0;
}
  1. 回调函数(事件处理)
// 注册回调函数类型
typedef void (*EventCallback)(int event_type);// 事件处理器
void event_handler(int event) {printf("Received event: %d\n", event);
}// 模拟事件触发函数
void trigger_event(EventCallback cb) {cb(1001);  // 触发事件
}int main() {trigger_event(event_handler);return 0;
}

五、核心注意事项

  1. 函数指针类型匹配:

    int func1(char) {...}
    void func2(int) {...}int (*fp1)(char) = func1;  // 正确
    int (*fp2)(int) = func1;   // 警告:参数类型不匹配
    void (*fp3)(int) = func2;  // 正确
    
  2. 现代C的改进:

    // C11新增的类型安全写法
    int (*fp)(int) = &func;  // 显式取地址
    int result = (*fp)(10);  // 标准调用方式
    
  3. 调试技巧:

    printf("Function address: %p\n", (void*)fp);  // 打印函数地址
    
  4. 跨平台问题:

    // Windows的__stdcall调用约定
    typedef int (__stdcall *WinAPIProc)(int);
    

掌握这两个概念的区分和使用,是理解C语言高级编程(如操作系统开发、驱动程序开发)的关键基础。建议通过实际项目(如实现命令行解析器、设计插件系统等)来加深理解。

http://www.xdnf.cn/news/472375.html

相关文章:

  • 【Linux】网络基础与socket编程基础
  • 深入理解JavaScript中的闭包:原理、应用与常见问题
  • 【stata】xtreg VS reghdfe
  • 位运算题目:找到最接近目标值的函数值
  • 新手入门系列-springboot项目初体验
  • C盘清理秘籍:快速提升系统性能
  • Python 调试扩展版本兼容问题解决纪实
  • 在自动化脚本中使用找色实现精确定位目标区域
  • docker 学习记录
  • uniapp x
  • 软件安全测试报告:检测商业软件安全性,发现潜在风险点?
  • 修复“ImportError: DLL load failed while importing lib: 找不到指定的程序”笔记
  • MySQL 误删除数据恢复全攻略:基于 Binlog 的实战指南
  • 深度学习入门:深度学习(完结)
  • 张量与Python标量:核心区别与计算图断开解析
  • 白平衡模块中普朗克曲线拟合硬件实现的猜想
  • ElfBoard技术实战|ELF 2开发板本地部署DeepSeek大模型的完整指南
  • MyBatis 的分页插件 c
  • 国产芯片LH001-91为什么可以代替TI的ADS1291?
  • 观QFramework框架底层逻辑有感
  • 丝杆升降机限位失灵深度剖析:从故障机理到智能监测方案
  • 硬件创新新纪元:从算力怪兽到便携革命,2025 年如何重新定义计算体验
  • unordered_set和unordered_map
  • 详细解释api
  • 不同进制的数据展示(十进制、十六进制、编码方式)
  • 理解 Viewport:让网页在手机端正确显示的秘诀
  • 星形测试卡:射线摄影获取焦点星卡射线照片的工具
  • win11安装Joplin Server私有化部署(docker)
  • 【应急响应工具教程】Windows日志快速分析工具——Chainsaw
  • 数智管理学(九)