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

C语言中函数指针和指针函数的定义及用法

在C/C++中,函数指针和指针函数是两个容易混淆但完全不同的概念。以下是它们的详细对比和学习指南,结合代码示例帮助你彻底掌握。

1. 函数指针(Function Pointer)

本质:一个指向函数的指针变量,用于动态调用函数。
用途:回调函数、策略模式、事件处理等。

语法与示例

// 声明一个函数指针类型(指向返回int,参数为int的函数)
typedef int (*FuncPtr)(int);// 示例函数
int square(int x) { return x * x; }
int cube(int x) { return x * x * x; }int main() {// 定义函数指针变量并指向函数FuncPtr ptr = square;printf("Square of 5: %d\n", ptr(5)); // 输出 25ptr = cube; // 切换指向的函数printf("Cube of 5: %d\n", ptr(5));   // 输出 125return 0;
}

关键点

  • 声明格式:返回值类型 (*指针名)(参数列表)
  • 应用场景:
    回调机制(如qsort的排序比较函数)。
    动态选择算法(如运行时选择加密函数)。

2. 指针函数(Pointer Function)

本质:一个返回指针的函数,本质上仍是函数。
用途:动态内存分配、返回数组/结构体指针等。

语法与示例

// 指针函数:返回int*的函数
int* createArray(int size) {int* arr = (int*)malloc(size * sizeof(int));for (int i = 0; i < size; i++) {arr[i] = i + 1;}return arr; // 返回动态分配的指针
}int main() {int* array = createArray(5);for (int i = 0; i < 5; i++) {printf("%d ", array[i]); // 输出 1 2 3 4 5}free(array); // 释放内存return 0;
}

关键点

  • 声明格式:返回值类型* 函数名(参数列表)

  • 注意事项:
    返回的指针需指向合法内存(如堆内存或静态变量)。
    避免返回局部变量的指针(会导致悬垂指针)。

3. 对比总结

特性函数指针指针函数
本质指向函数的指针变量返回指针的函数
声明示例int (*ptr)(int)int* func(int)
内存占用存储函数地址(通常4/8字节)函数本身无特殊内存占用
典型用途回调、动态绑定返回动态数据结构的指针
危险点空指针调用导致崩溃内存泄漏或悬垂指针

4. 进阶应用

函数指针数组

int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }int main() {int (*ops[2])(int, int) = {add, sub}; // 函数指针数组printf("Add: %d\n", ops[0](3, 2));    // 输出 5printf("Sub: %d\n", ops[1](3, 2));    // 输出 1return 0;
}

复杂声明解析(右左法则)

  • 函数指针的指针函数:
    int* (funcPtr)(int) → funcPtr是指针,指向一个返回int的函数。

5. 常见面试题

以下代码的输出是什么?

void foo() { printf("Hello"); }
int main() {void (*ptr)() = foo;ptr();return 0;
}

答案:输出Hello,函数指针调用。

找出错误:

int* badFunc() {int x = 10;return &x; // 返回局部变量的地址!
}

错误:返回局部变量指针,函数结束后x被销毁,导致悬垂指针。

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

相关文章:

  • 【leetcode】19. 删除链表的倒数第N个节点
  • CppCon 2014 学习第3天:Viewing the world through array-shaped glasses
  • 计算机网络常见体系结构、分层必要性、分层设计思想以及专用术语介绍
  • Mybatis(Plus)对JSON / Array类型进行序列化
  • 2.环境搭建
  • 项目更改权限后都被git标记为改变,怎么去除
  • ai绘制mg人物半侧面头型
  • 2025年OE SCI2区TOP,进化麻雀搜索算法ESSA+海洋阻尼器迟滞建模与辨识,深度解析+性能实测
  • 进程同步机制-信号量机制-记录型信号量机制中的的wait和signal操作
  • 未来楼宇自控系统升级优化,为绿色建筑发展注入更强动力支撑
  • 大模型应用开发之评估
  • 浅谈学习(费曼学习法)
  • 四叉树实现四边形网格
  • OpenGL —— 2.9.1、摄像机之模拟CS鼠标视角转动,可切换线框模式显示(附源码,glfw+glad)
  • 力扣刷题Day 64:括号生成(22)
  • 什么是物化视图(Materialized View)?
  • Redis的大Key问题如何解决?
  • [预训练]Encoder-only架构的预训练任务核心机制
  • 【Day39】
  • 【Doris基础】Apache Doris数据模型全面解析:选择最适合你的数据组织方式
  • ProfibusDP转DeviceNet协议转换网关应用于S7-300PLC控制埃斯顿DeviceNet焊机项目
  • unity—特效闪光衣服的设置
  • 亚马逊桌布运营中的利润核算与优化:从成本管控到决策升级
  • MonoPCC:用于内窥镜图像单目深度估计的光度不变循环约束|文献速递-深度学习医疗AI最新文献
  • 5.3.1_2二叉树的层次遍历
  • 博客摘录「 Activiti7工作流引擎:基础篇(二) 自动生成表结构」2024年9月13日
  • 更换Homebrew 源
  • 【C/C++】闭包的几个用处
  • 如何用Go创建一个 deployment 到容器拉起来的全流程
  • python 制作复杂表格报告