【函数指针】

函数指针详解

什么是函数指针

函数指针是指向函数地址的指针变量。与普通指针存储变量地址不同,函数指针存储的是函数在内存中的地址。

cpp 复制代码
// 普通指针:存储变量地址
int a = 10;
int* p = &a;

// 函数指针:存储函数地址
void test() { std::cout << "hello" << std::endl; }
void (*p)() = test; // p存储test函数的地址

为什么需要函数指针

函数指针的核心价值是让函数像变量一样被传递,实现运行时动态选择执行的函数。

cpp 复制代码
void A() {}
void B() {}

void run(void (*f)()) {
    f(); // 执行传入的函数
}

run(A); // 执行A
run(B); // 执行B

这是工厂模式、策略模式等多种设计模式的基础。

直观理解

  • 普通变量:存储数据
  • 函数指针:存储行为(操作步骤)

核心区别:

数据指针指向数据,函数指针指向行为

应用场景

函数指针可以像数据一样存储在各种容器中:

  • map:实现注册模式(如插件系统)
  • vector:存储多个函数
  • 数组:实现简单的命令分发

语法

基本形式

cpp 复制代码
int add(int a, int b) { return a + b; }

// 函数指针定义
int (*p)(int, int) = add;
// 调用
int result = p(2, 3);

简化写法(typedef/using)

cpp 复制代码
// 传统写法
typedef int (*FuncType)(int, int);
// C++11+ 现代写法
using FuncType = int(*)(int, int);

FuncType p = add;

无参数/无返回值

cpp 复制代码
void hello() { std::cout << "Hello" << std::endl; }
void (*fptr)() = hello;
fptr();

作为参数

cpp 复制代码
void execute(void (*func)()) {
    func();
}

execute(hello);

作为返回值

推荐写法(使用typedef/using简化):

cpp 复制代码
using FuncType = int(*)(int, int);

FuncType getFunc() {
    return add;
}

// 1. 调用getFunc函数,获取add函数的指针
FuncType p = getFunc();
// 2. 调用add函数
int result = p(1, 2);

形式总结

场景 形式 示例
指针变量 返回类型 (*指针名)(参数列表) int (*p)(int, int) = add;
typedef/using typedef 返回类型 (*类型名)(参数列表) typedef int(*FuncType)(int, int);
作为参数 void f(返回类型 (*param)(参数列表)) void run(int (*func)(int, int))
作为返回值 typedef/using类型名 f() FuncType getFunc() { return add; }

关键规律(*名字) 必须用括号包起来,否则编译器会认为是函数声明。

本质

函数指针的本质是把函数当成"任务"传递

cpp 复制代码
void life(void (*f)()) {
    f(); // 执行传入的任务
}

void eat() { std::cout << "吃饭" << std::endl; }
life(eat); // 传递"吃饭"任务

简单来说:

普通参数传数据,函数指针传动作

实际应用

你可能已经在使用函数指针的概念,只是换了个名字:

  • 虚函数
  • std::function
  • Lambda表达式
  • 回调函数

这些底层都基于函数指针的思想。

复杂声明解析

对于复杂的函数指针声明:

cpp 复制代码
Plugin* (*FactoryFunc)();

解析:FactoryFunc 是一个返回 Plugin* 且无参数的函数指针。

总结

函数指针是C++中强大的特性,它允许我们:

  • 动态选择执行的函数
  • 实现回调机制
  • 构建灵活的设计模式
  • 提高代码的模块化和可扩展性

核心理解:普通指针指向数据,函数指针指向代码

相关推荐
老当益壮梁奶奶43 分钟前
Linux软件编程学习笔记(二)Linux文件IO编程入门:从fopen到fgetc
linux·c语言·c++·笔记·学习
雪的季节1 小时前
C++ 高级(泛型编程与模板)(有空再研究吧)
c++
三十岁老牛再出发1 小时前
8月21日总结
c++·python
不可求~2 小时前
C++ 报错交给 AI 之前,先准备好这 8 类信息
开发语言·c++·人工智能
别动我齐刘海13 小时前
机器人运动控制学习2——基础进阶
c++·人工智能·神经网络·学习·目标检测·机器学习·机器人
傻啦嘿哟13 小时前
英雄联盟皮肤爬虫:爬取全皮肤价格与特效,做比价工具
java·c++·爬虫
码匠许师傅14 小时前
【C++ 面试真题】24. 聊聊 C++ 的时间日期处理
java·c++·面试
闻道且行之14 小时前
图片处理助手|泊松融合原理 + C++ 工程实现,seamlessClone 三模式一次讲透
数据库·c++·人工智能·opencv
莫浅子15 小时前
day01-USB架构与枚举
c++·单片机·嵌入式驱动
小欣加油16 小时前
leetcode3069 将元素分配到两个数组中I
数据结构·c++·算法·leetcode·职场和发展