7.8函数指针
0.前言
模版函数的指针似乎还有很多知识值得学习,回头再填坑~
1.指向函数的指针
函数是由指令序列构成的,代码存储在一块空间中,因此也有一个指针(函数的入口)
调用函数可以用过调用指向这个函数的指针实现(但这个函数得有指针
试想,我们通过指针调用一个函数,当然需要知道函数的返回值类型、参数个数及类型。因此,这些信息需要在定义指针时体现
定义格式:
返回类型 (*指针变量名)(形式参数表);
赋值格式:
指针变量名=函数名;
特别注意,第一对括号要保留,函数调用符号()的优先级高于指针符号,编译器会认为定义了返回指针类型的函数。*
例如:
char trans(char c){
if(c>='a'&&c<='z')c-='a'-'A';
else if(c>='A'&&c<='Z')c+='a'-'z';
return c;
}//trans(char c)是大小写转换的函数
char (*f)(char);
f=trans;
cout<<f(a);//结果为A
那么,每一个函数都有对应的指针,对吧?
对吗?
我们可以用c++库函数,max(3,5)做一个尝试
编译器这么说:no matches converting function ‘max’ to type ‘int (*)(int,int)’
什么情况?
回顾定义,函数指针需要给出函数的返回值类型。但max(3,5)可以返回整型,max(3.1,4.2)可以返回浮点型——max函数是一个函数模版
没有固定的返回类型!
所以……为什么不能有指针模版呢?
对呀
template<class T> T (*f)(T,T);
是不是大功告成呢?也不是
函数模版是没有实体的(不占用空间的意思?)因此,不能用这种方式定义
所以这类型的函数,没有简单的指针(
2.函数指针作为函数参数
函数可以用指针表示,作用的领域就大大增加
提供了很多便利
sort()函数,一个排序函数,非常方便
但很多人不知道,sort()可以有第三个参数
template <class RandomAccessIterator> void sort (RandomAccessIterator first, RandomAccessIterator last);
template <class RandomAccessIterator, class Compare> void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
也就是说,第一种(我们常见的)就是默认的升序排列
第二种则加入了一个comp函数,我们可以通过这个函数实现很多功能,例如:实现降序排列,结构体排序,等等
struct rational{
int a,b;
friend bool operator<(const rational &a,const rational &b){//重载一下?
return a.a*b.b<a.b*b.a;
}
};
bool cmp(const rational &a,const rational &b){
return a<b;
}//对rational类的比大小
void sort(rational *a,rational *b,bool (*f)(const rational&,const rational&)){
rational *p,*q;
for(p=a;p<b;p++){
for(q=p+1;q<b;q++){
if(f(*p,*q)){//降序排列
rational tmp;
tmp=*p;
*p=*q;
*q=tmp;
}
}
}
}
//rank by cmp
//对有理数类型(丐版)的sort函数(冒泡排序,理解大意即可qwq
3.函数指针用于菜单选择
对于并列的多个①返回类型相同②形式参数表相同的函数,我们可以定义函数指针数组,(打包存放,便于使用~
比如这个,非常简单的优先队列展示,通过函数指针数组实现(期末考试最后一个大题这么写,会不会简单一点?
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
priority_queue <int> q;
void display(){
int *a=new int[q.size()];
int tmp=q.size();
for(int i=0;i<tmp;i++){
a[i]=q.top();
q.pop();
cout<<a[i]<<" ";
}
for(int i=0;i<tmp;i++){
q.push(a[i]);
}
delete []a;
}
void add(){
int a;
cin>>a;
q.push(a);
}
int main(){
void (*f[3])()={NULL,display,add};
int select;
while(1){
cin>>select;
if(select==0)return 0;
else f[select]();
}
return 0;
}