c++ 函数指针

目录

起点:编程的基本事实

推导:函数也有“地址”吗?

什么是函数指针?

为什么需要函数指针?

解决方案:动态选择

什么时候用函数指针?

总结

起点:编程的基本事实

  1. 程序由指令组成:程序的核心是告诉计算机做什么,比如“计算两个数的和”或“打印一条消息”。

  2. 指令有名字:这些“做什么”的操作通常用函数来表示,比如 add(a, b) 或 print(message)。函数名就像一个标签,你通过它找到并执行某个操作。

  3. 变量可以存数据:在 C++ 中,变量可以保存数字、文字等数据,比如 int x = 5。

  4. 名字和地址的区别:当你说“找 John”,你可能直接说名字,但有时你需要知道 John 的具体位置(比如他的地址或电话号码)。

基于这些事实,我们来推导函数指针是什么。

推导:函数也有“地址”吗?

事实 1:函数是代码块

函数比如 print 不是数据,而是一段代码,告诉计算机怎么执行某个任务。但这些代码在内存中有固定的位置,就像你的家在某个街道上有具体门牌号。

事实 2:计算机用地址访问内存

计算机通过内存地址找到数据或代码。比如,变量 x 的值 5 存放在某个内存位置,地址可能是 0x1000。同样,函数 print 的代码也存放在内存的某个位置,有它自己的地址。

事实 3:我们需要动态选择函数

有时候,程序需要灵活地决定“用哪个函数”。比如:

  • 有两个函数:add(加法)和 multiply(乘法)。

  • 用户输入“+”就用 add,输入“*”就用 multiply。 但如果每个选择都要写一大堆 if-else,代码会很乱。能不能像变量一样,把函数“存起来”,然后根据需要“调用”它?

推导:函数的“地址”可以被引用

如果函数有内存地址,我们能不能像存变量地址一样,存下函数的地址,然后随时用它调用对应的函数?答案是肯定的!这就是函数指针的核心思想。

什么是函数指针?

用通俗的话说,函数指针就是“函数的地址标签”。它让你可以:

  • 把一个函数的“位置”(内存地址)存进一个变量。

  • 之后通过这个变量去“找到”并“调用”那个函数。

就像:

  • 你有一个电话本,里面存了朋友的电话号码。

  • 函数指针就是电话号码,你可以通过它“拨打”某个函数,让它“接听”(执行)。

在 C++ 中,函数指针的写法看起来复杂,但本质很简单。例如:

void printHello() {
    std::cout << "Hello!" << std::endl;
}

int main() {
    void (*ptr)() = printHello; // ptr 是一个函数指针,指向 printHello
    ptr(); // 通过指针调用函数,效果等同于 printHello()
    return 0;
}
  • ptr 是一个变量,但它不存数据,而是存了 printHello 函数的地址。

  • 当你写 ptr();,就像拨打了 printHello 的“电话”,函数就被执行了。

为什么需要函数指针?

从第一性原理看,函数指针解决了一个核心问题:灵活性。

问题:静态选择不好用

假设你写了个程序,要根据用户选择执行不同操作:

  • 如果用户选 1,调用 add。

  • 如果用户选 2,调用 multiply。

传统方法可能是:

但如果有 100 个选择呢?代码会变得很长、很乱。

解决方案:动态选择

函数指针让你可以:

  • 把所有可能的函数(add、multiply 等)存进一个“列表”(数组或变量)。

  • 根据用户选择,取出对应的函数指针,然后直接调用。

比如:

void add(int a, int b) { std::cout << a + b << std::endl; }
void multiply(int a, int b) { std::cout << a * b << std::endl; }

int main() {
    void (*funcPtr)(int, int); // 定义一个函数指针,可以指向任何接受两个 int 参数、无返回值函数

    int choice;
    std::cin >> choice;

    if (choice == 1) funcPtr = add;
    else funcPtr = multiply;

    funcPtr(5, 3); // 根据选择调用对应的函数
    return 0;
}
  • 这里 funcPtr 就像一个“遥控器”,可以切换到不同的函数。

  • 这种方式比写一大堆 if-else 更灵活、更简洁。

什么时候用函数指针?

从第一性原理看,函数指针在以下场景有价值:

  1. 需要动态选择:当程序运行时要决定调用哪个函数(比如回调、事件处理)。

  2. 函数作为参数:当你想把函数本身传给另一个函数,比如排序算法中的比较函数。

  3. 代码复用:避免重复写类似逻辑,只改变函数行为。

比如,C++ 的 std::sort 允许你传入一个比较函数指针,决定如何排序。

总结

函数指针就是“函数的地址变量”。它让你:

  • 像存数据一样存函数。

  • 随时切换、调用不同的函数。

就像你有一个魔法遥控器,可以按下不同按钮调用不同的服务(函数)。它的存在是因为程序需要更灵活、更高效地处理“做什么”的选择,而不是死板地写死逻辑。

从第一性原理看,函数指针是程序设计中对“动态行为”需求的自然产物,简化了代码,增强了可扩展性。

你可能感兴趣的:(C/C++,c++,开发语言)