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

C和C++的函数指针

一)C 语言中的函数指针
1)函数指针的定义和声明:
函数指针是指向函数的指针变量。其声明格式为:
返回值类型 (*指针变量名)(参数列表);。
例如,int (*func_ptr)(int, int);
声明了一个名为func_ptr的函数指针,它可以指向返回值为int,并且有两个int类型参数的函数。
例如,有一个函数int add(int a, int b) { return a + b; },可以将这个函数的地址赋给函数指针:func_ptr = add;。在 C 语言中,函数名本身就代表函数的入口地址,所以这里add就是函数add的地址。
函数指针的调用:
通过函数指针调用函数的方式是(*函数指针名)(参数列表);。例如,int result = (func_ptr)(3, 5);就相当于调用add(3, 5),result的值为 8。也可以省略,写成func_ptr(3, 5);,这两种写法在 C 语言中是等价的。
函数指针的应用场景:
作为函数参数:函数指针可以作为函数的参数,用于实现回调函数。例如,在一个排序算法函数中,可以将比较函数作为参数传递进去,这样就可以根据不同的比较规则进行排序。

#include <stdio.h>
// 比较函数的类型定义
typedef int (*compare_func)(int, int);
// 冒泡排序函数,接受一个比较函数指针作为参数
void bubble_sort(int arr[], int n, compare_func cmp) 
{
    for (int i = 0; i < n - 1; ++i)
     {
        for (int j = 0; j < n - i - 1; ++j) 
        {
            if (cmp(arr[j], arr[j + 1]) > 0) 
            {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

// 比较函数,用于升序排序

int ascending(int a, int b) 
{
    return a - b;
}
int main() 
{
    int arr[] = {5, 4, 3, 2, 1};
    int n = sizeof(arr) / sizeof(arr[0]);
    // 使用升序比较函数进行排序
    bubble_sort(arr, n, ascending);
    for (int i = 0; i < n; ++i) 
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

在这个例子中,bubble_sort函数接受一个函数指针cmp,通过这个函数指针调用不同的比较函数来实现不同规则的排序。
函数指针数组:可以创建函数指针数组,用于存储多个函数的地址,实现函数的动态调用。例如,一个简单的计算器程序,可以根据用户的选择调用不同的运算函数。
c

#include <stdio.h>
// 加法函数
int add(int a, int b) 
{
    return a + b;
}
// 减法函数
int subtract(int a, int b) 
{
    return a - b;
}
// 乘法函数
int multiply(int a, int b) 
{
    return a * b;
}
// 除法函数
int divide(int a, int b) 
{
    return a / b;
}
int main() 
{
    int (*func_array[])(int, int) = {add, subtract, multiply, divide};
    int choice;
    int a, b;
    printf("请选择运算(0:加法, 1:减法, 2:乘法, 3:除法): ");
    scanf("%d", &choice);
    printf("请输入两个数字: ");
    scanf("%d %d", &a, &b);
    int result = func_array[choice](a, b);
    printf("结果: %d\n", result);
    return 0;
}

这里func_array是一个函数指针数组,根据用户的选择choice,调用相应的函数进行运算。
二)C++ 语言中的函数指针
函数指针的定义和声明:C++ 中的函数指针定义和声明方式与 C 语言基本相同。例如,double (*func_ptr)(double);声明了一个可以指向返回值为double,有一个double类型参数的函数的函数指针。
函数指针与 C++ 特性结合:
与类成员函数的结合(需要注意):在 C++ 中,普通函数指针不能直接指向类的成员函数,因为类成员函数有一个隐含的this指针。如果要指向类成员函数,需要使用类成员函数指针。例如:
cpp

class MyClass 
{
public:
    int member_func(int a) { return a * 2; }
};
int main() 
{
    MyClass obj;
    int (MyClass::*member_func_ptr)(int) = &MyClass::member_func;
    int result = (obj.*member_func_ptr)(3);
    // 或者使用指针形式:MyClass* ptr = &obj; int result = (ptr->*member_func_ptr)(3);
    printf("结果: %d\n", result);
    return 0;
}

这里int (MyClass::*member_func_ptr)(int)是类成员函数指针的声明,通过(obj.*member_func_ptr)(3)或者(ptr->*member_func_ptr)(3)的方式来调用成员函数。
与函数重载的结合:C++ 中的函数重载会导致函数指针的赋值和调用需要更加谨慎。只有参数列表和返回值类型完全匹配的函数才能赋值给对应的函数指针。例如:
cpp

#include <iostream>
// 重载函数
void print(int a) 
{
    std::cout << "整数: " << a << std::endl;
}
void print(double a) 
{
    std::cout << "浮点数: " << a << std::endl;
}
int main() 
{
    void (*func_ptr)(int) = print;
    func_ptr(5);
    // 以下代码会出错,因为函数指针类型不匹配
    // void (*func_ptr2)(double) = func_ptr;
    return 0;
}

在这个例子中,func_ptr只能指向参数为int的print函数,不能直接指向参数为double的print函数。如果要根据不同的参数类型调用不同的重载函数,可以通过函数模板或者类型转换等方式来实现。
C++ 和 C 语言函数指针的比较
语法一致性:C++ 和 C 语言在函数指针的基本语法上是一致的,包括定义、声明和调用的方式。这使得在 C++ 中可以方便地使用 C 语言风格的函数指针,也便于将 C 语言代码中的函数指针相关代码移植到 C++ 环境中。
与语言特性结合的差异:C++ 有更多的高级特性,如类成员函数指针和函数重载,这些特性在和函数指针结合时需要特别注意。在 C 语言中不存在类成员函数指针的概念,也没有函数重载,所以在函数指针的使用上相对更直接。另外,C++ 的类型检查更加严格,对于函数指针的类型匹配要求也更高,这有助于减少一些潜在的错误。


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

相关文章:

  • 游戏引擎学习第52天
  • 【mybatis】mapper.xml文件DOCTYPE含义
  • 【Rust自学】3.4. 函数和注释
  • LLM常见面试题(16-20题)
  • 牛客--字符串加密
  • 常见软件设计模式介绍:三层架构、MVC、SSM、EDD、DDD
  • 通过使用 contenteditable=“true“,我们彻底防止了 iOS 系统键盘的弹出
  • 家具购物小程序+php
  • Pytest-Bdd vs Behave:选择最适合的 Python BDD 框架
  • AIDD-人工智能药物设计-ChemDraw Mac版pojie安装
  • 基于Spring Boot的数码产品抢购系统
  • 常见的数据结构和应用场景
  • Serverless核心组件、最佳实践及性能优化
  • 向量数据库Faiss C++
  • Hololens 2 Unity VS2019编译报错解决方案
  • Go, Jocko, Kafka
  • 渗透测试学习笔记(五)网络
  • u3d动画系统六【动画根运动】
  • AI视频配音技术创新应用与商业机遇
  • 基于 Cell 架构的安全防护:现代应用程序领域的深度剖析与应对策略