函数指针的详细介绍与举例说明

函数指针

函数指针的声明形式

数据类型 (*函数名)(形参列表)  

 

函数指针的作用

我们知道函数与函数形参是两个不太一样的概念:

函数体

动作

函数形参

数据

内存中,不管是动作还是数据都使用16进制的数据存储在内存当中,用地址来访问。其实将函数作为一个地址来进行访问就相当于“将动作数据化”。这样的话,我们就做到了“一切皆可使用地址来访问”。这样做给我们带来的优势如下:

内存中的数据均有其对应的地址,我们可以将这些地址封装在一个数组中,对他们使用统一的格式进行访问,这样的程序条理清晰对象明确,例如:

对象

动作

小明,小李

约会

小明,小强

吃饭

大明,李四

看电影

大明,小明

看电影

我们可以编写如下程序实现上述函数功能:

 

函数指针的应用

函数的嵌套使用

#include <iostream>  
using namespace std;  
  
//using f1 = void(*)(int*, int*); // 相当于定义一个函数指针的模板  
typedef void(*f1)(int*, int*); // 相当于定义一个函数指针的模板(与前面这一行代码作用相同)  
  
void swap1(int* a, int* b)  
{  
    int temp = 0;  
    temp = *a;  
    *a = *b;  
    *b = temp;  
}  
  
void Operation(int* a, int* b, f1 Fun)  
{  
    Fun(a, b);  
}  
  
int main()  
{  
    int a = 2, b = 4;  
    Operation(&a, &b, swap1);  
    cout << a << endl;  
    cout << b << endl;  
}

  

以上实例,展示了在某一个函数中使用其他函数的示例,这种调用方式打破了“只可以在该函数内使用该函数之前定义过或声明过的函数”的规定,使用起来很方便,使得函数也可以像数据一样传入其他函数中使用。

C语言的“面向对象”结构体

C语言最重要的复合数据类型就是结构体,但是我们一般不知道的是“结构体也可以是想面向对象的功能”。面向对象最简单的解释就是“结构体 = 数据(数据成员) + 数据处理(函数)”,当我们输入数据后,这个结构体就如同黑箱一样,有许多外围接口可以供我们得到我们想要的结果,但是其中的过程并不是我们想关注的,C风格的面向对象的简单示例:

#include <iostream>  
using namespace std;  
  
struct Student   
{  
// 数据成员  
    int StudNum;  
    float Mark;  
    float Height;  
    float Weight;  
// 数据处理  
    bool (*TestExam)(float Height, float Weight, float Mark);  
    void (*ShowInf)(int StudNum, float Height, float Weight, float Mark, bool (*TestExam)(float,float,float));  
};  
  
bool Student_TestExam(float Height, float Weight, float Mark)  
{  
    if (Height > 175 && Weight < 150 && Mark>90)  
    {  
        return 1;  
    }  
    else  
    {  
        return 0;  
    }  
}  
using Func_TestExam = bool(*)(float, float, float);  
void Student_ShowInf(int StudNum,float Height, float Weight, float Mark,Func_TestExam TestExam)  
{  
    bool temp = TestExam(Height, Weight, Mark);  
    if (temp == 1)  
    {  
        cout << "学号为" << StudNum << "的同学综合成绩合格" << endl;  
    }  
    else  
    {  
        cout << "学号为" << StudNum << "的同学综合成绩不合格" << endl;  
    }  
}  
  
int main()  
{  
    Student Stud1 = { 7,176,120,95 };  
    Stud1.TestExam = Student_TestExam;  
    Stud1.ShowInf = Student_ShowInf;  
    Stud1.ShowInf(Stud1.StudNum, Stud1.Height, Stud1.Weight, Stud1.Mark, Stud1.TestExam);  
}  

 

如上程序,我们实现了一个类似于“封装类”的结构体,实现功能如下:

输入数据

学生的学号,学生的体重,学生的身高,学生的期末成绩

输出数据

该学生的综合评测是否合格

函数指针实现类似于多态的功能

#include <iostream>  
using namespace std;  
  
typedef int (*Func)(int, int);  
int Minus(int a, int b)  
{  
    return a - b;  
}  
int Add(int a, int b)  
{  
    return a + b;  
}  
  
int main()  
{  
    Func operation;  
    operation = Minus;  
    cout << operation(1, 3) << endl;  
    operation = Add;  
    cout << operation(1, 3) << endl;  
}  

 

我们从上述例程看到:相同的函数operation在赋予了两个不同的函数实现过程之后,输入相同的形参可以进行“返回值相同,形参相同但是实现方式不同”的数据操作。这一点有点像多态,但是与“C++中面向对象的多态”还是有一定的差距的。

三种声明函数指针的方式

// 方法一:
typedef int(*FuncName)(int, int); // FuncName为函数类型名,Func1为函数指针名  
FuncName Func1;  

// 方法二:
using FuncName = int(*)(int, int); // FuncName为函数类型名,Func1为函数指针名  
FuncName Func1;  

// 方法三:
int(*Func1)(int, int) = Function; // Function在这里是已经实现的函数的函数名字  

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥肥胖胖是太阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值