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

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.lryc.cn/news/2397245.html

相关文章:

  • Spring Boot DevTools 热部署
  • unix/linux source 命令,其基本属性、语法、操作、api
  • FPGA仿真中阻塞赋值(=)和非阻塞赋值(<=)区别
  • LabVIEW轴角编码器自动检测
  • MySQL数据库从0到1
  • WiFi万能钥匙鲲鹏服务器部署 TiDB 集群实战指南
  • 正则表达式的前世今生
  • Vue 核心技术与实战智慧商城项目Day08-10
  • TCP/IP协议精华总结pdf分享
  • 组件化:软件工程化的基础
  • ⚡️ Linux grep 命令参数详解
  • 2025年第三届CCF·夜莺开源创新论坛通知
  • GMDCMonitor企业版功能分享0602
  • automa
  • Warm-Flow发布1.7.3 端午节(设计器流和流程图大升级)
  • 【存储基础】SAN存储基础知识
  • 2025年ESWA SCI1区TOP,改进成吉思汗鲨鱼算法MGKSO+肝癌疾病预测,深度解析+性能实测
  • 精益数据分析(93/126):增长率的真相——从数据基准到科学增长策略
  • MAC上怎么进入隐藏目录
  • Spark-TTS: AI语音合成的“变声大师“
  • 【Python 进阶3】常见的 call 和 forward 区别
  • WEB3——简易NFT铸造平台之nft.storage
  • 一元函数积分
  • 6年“豹变”,vivo S30系列引领手机进入场景“体验定义”时代
  • Pytorch的梯度控制
  • linux驱动开发(1)-内核模块
  • AI产品风向标:从「工具属性」到「认知引擎」的架构跃迁​
  • 前端八股之CSS
  • ps自然饱和度调整
  • 有公网ip但外网访问不到怎么办?内网IP端口映射公网连接常见问题和原因