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

深入解析C++函数指针与指针函数:从原理到实战

🔗 运行环境:C/C++

🚩 撰写作者:左手の明天

🥇 精选专栏:《python》

🔥  推荐专栏:《算法研究》

🔐#### 防伪水印——左手の明天 ####🔐

💗 大家好🤗🤗🤗,我是左手の明天!好久不见💗

💗今天分享【C/C++】——函数指针与指针函数💗

📆  最近更新:2025 年 02 月 22 日,左手の明天的第 354 篇原创博客

📚 更新于专栏:C/C++入门与进阶

🔐#### 防伪水印——左手の明天 ####🔐


一、概念区分

1. 指针函数(Pointer Function)

  • 定义:返回指针类型的函数

  • 本质:普通函数,仅返回值是指针

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

示例如下:

int* getPointer(int value) {
    int* ptr = new int(value);
    return ptr;
}

2. 函数指针(Function Pointer)

  • 定义:指向函数的指针变量

  • 本质:指针变量,存储函数入口地址

  • 声明形式返回类型 (*指针名)(参数列表)

它可以用来调用一个函数或者将一个函数作为参数传递给另一个函数。定义函数指针时,需要指定它所指向的函数的返回类型和参数类型。示例如下:

int add(int a, int b) {
    return a + b;
}

int (*funcPtr)(int, int);

int main() {
    funcPtr = &add;  // 将函数指针指向 add 函数
    std::cout << funcPtr(2, 3) << std::endl;  // 输出 5
    return 0;
}

二、指针函数详解

1. 基础用法

#include <iostream>

// 指针函数:返回int类型指针
int* createArray(int size) {
    int* arr = new int[size];
    for(int i=0; i<size; ++i) {
        arr[i] = i * 10;
    }
    return arr;
}

int main() {
    int* myArray = createArray(5);
    
    for(int i=0; i<5; ++i) {
        std::cout << myArray[i] << " "; // 输出:0 10 20 30 40
    }
    
    delete[] myArray; // 必须手动释放内存
    return 0;
}

2. 注意事项

  • 避免返回局部变量指针

  • 动态内存需要手动释放

  • 推荐使用智能指针(C++11+)

// 危险示例:返回局部变量指针
int* dangerousFunc() {
    int localVar = 42;
    return &localVar; // 警告!返回局部变量地址
}

三、函数指针深度解析

1. 基本声明与使用

#include <iostream>

// 普通函数
int add(int a, int b) {
    return a + b;
}

int subtract(int a, int b) {
    return a - b;
}

int main() {
    // 声明函数指针类型
    int (*operation)(int, int);
    
    operation = &add; // 绑定加法函数
    std::cout << "10 + 5 = " << operation(10, 5) << std::endl;
    
    operation = subtract; // 绑定减法函数(&可选)
    std::cout << "10 - 5 = " << operation(10, 5) << std::endl;
    
    return 0;
}

2. 高级应用:回调函数

#include <vector>

// 回调函数处理数组
void processArray(std::vector<int>& arr, void (*callback)(int&)) {
    for(auto& num : arr) {
        callback(num);
    }
}

// 回调函数示例
void square(int& num) {
    num = num * num;
}

void print(int& num) {
    std::cout << num << " ";
}

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    
    processArray(numbers, square);  // 平方运算
    processArray(numbers, print);  // 输出:1 4 9 16 25
    
    return 0;
}

3. 使用typedef/using简化

// 使用typedef定义函数指针类型
typedef int (*MathOperation)(int, int);

// C++11 using语法
using MathOp = int (*)(int, int);

int multiply(int a, int b) {
    return a * b;
}

int main() {
    MathOperation op1 = add;
    MathOp op2 = multiply;
    
    std::cout << op1(3,4) << " " << op2(3,4) << std::endl;
    return 0;
}

四、综合对比表

特性指针函数函数指针
本质返回指针的函数指向函数的指针变量
声明关键字*在返回类型后(*指针名)包裹
内存管理需要关注返回值生命周期自动管理函数地址
典型应用场景动态对象创建、工厂模式回调机制、策略模式
复杂度单层指针操作可能涉及多级指针

五、复杂场景应用

1. 返回函数指针的函数

#include <iostream>

int add(int a, int b) { return a+b; }
int sub(int a, int b) { return a-b; }

// 返回函数指针的函数
int (*getOperation(char op))(int, int) {
    switch(op) {
        case '+': return &add;
        case '-': return &sub;
        default: return nullptr;
    }
}

int main() {
    int (*operation)(int, int) = getOperation('+');
    std::cout << "5 + 3 = " << operation(5, 3) << std::endl;
    return 0;
}

2. 函数指针数组

#include <iostream>

void morning() { std::cout << "Good morning!\n"; }
void afternoon() { std::cout << "Good afternoon!\n"; }
void evening() { std::cout << "Good evening!\n"; }

int main() {
    void (*greetings[3])() = {morning, afternoon, evening};
    
    for(int i=0; i<3; ++i) {
        greetings[i]();
    }
    return 0;
}

六、最佳实践与常见陷阱

1. 安全建议

  • 使用nullptr初始化函数指针

  • 调用前检查指针有效性

  • 优先使用C++11的std::function

#include <functional>

int main() {
    // 更安全的现代C++方式
    std::function<int(int,int)> safeOp = add;
    std::cout << safeOp(7, 8) << std::endl;
    return 0;
}

2. 常见错误

// 错误1:参数类型不匹配
double (*wrongOp)(float, float) = add; // 错误!类型不兼容

// 错误2:错误调用方式
int (*op)(int, int) = add;
op = 10; // 错误!不能赋整数值

七、性能与优化

  • 函数指针调用比虚函数快约15%(无分支预测失败)

  • 在紧密循环中建议使用模板替代

  • 现代CPU的间接调用惩罚已显著降低


关键点总结

  1. 指针函数关注返回值类型,函数指针关注参数匹配

  2. 使用typedef/using提升代码可读性

  3. 优先使用智能指针管理动态内存

  4. C++11后推荐std::function+lambda表达式

通过本文的代码实践和原理分析,读者应该能够准确区分和使用这两类重要特性。建议在需要动态行为选择的场景多用函数指针,而在需要生成动态数据的场景合理使用指针函数。


扩展阅读

  1. 《Effective C++》条款41:了解隐式接口和编译期多态

  2. C++17的std::invoke统一调用机制

  3. 函数指针与多态的性能对比分析


 


http://www.kler.cn/a/557146.html

相关文章:

  • bind()的概念和使用案例
  • USC安防平台之视频切片
  • 驱动的三个框架
  • 52类110个主流Java组件和框架
  • IEEE官方期刊缩写查询pdf分享
  • 蓝桥杯每日一题--第一周(包含五题)
  • EP零散笔记
  • 神经网络防“失忆“秘籍:弹性权重固化如何让AI学会“温故知新“
  • 泥沙输送的DEM-CFD耦合案例
  • Kubernetes控制平面组件:APIServer 基于 Webhook Toeken令牌 的认证机制详解
  • 广度优先搜索详解--BFS--蒟蒻的学习之路
  • 沃丰科技大模型标杆案例|周大福集团统一大模型智能服务中心建设实践
  • 蓝桥杯备赛-基础训练(三)哈希表 day15
  • 【论文阅读笔记】知识蒸馏:一项调查 | CVPR 2021 | 近万字翻译+解释
  • 垃圾回收知识点
  • 力扣-回溯-78 子集
  • 微信小程序-二维码绘制
  • ncrfp:一种基于深度学习的端到端非编码RNA家族预测新方法
  • E - Palindromic Shortest Path【ABC394】
  • 洛谷 P4644 USACO05DEC Cleaning Shift/AT_dp_w Intervals 题解