这一节讲函数指针,学C的时候很难理解,这次要攻克过去!
先看看这篇通俗易懂的文章,https://blog.csdn.net/afei__/article/details/80549202——阿飞_的博客
函数指针
- 为什么需要?
答:因为我想通过一个指针,指向不同的几个函数,更方便我在函数内或者是主函数内调用函数,不必在写具体什么函数了,省工作量 - 函数指针形式很复杂,慎用。
- 下面举一个例子来说明这个东西。
const vector<int>* (*seq_ptr)(int);
这是一个函数指针,seq_ptr被定义成函数指针,他可以指向具有返回类型和参数表的任何一个函数。 - 关于
vector<int>* (*seq_ptr)(int); 与 vector<int>* *seq_ptr(int);
的区别(前者像是一个二级指针)
解答如下(摘自pump天天学习的解答,原网址)
举个简单的例子:
int fun(int)
//这个是一个名为fun的函数,返回值是int
形参是int
int (*pfun)(int)
//而这个是一个函数指针,pfun指向的是一个返回值和形参都是int
的函数再来个循序渐进点的
int* fun(int)
//这个是一个名为fun的函数,但他的返回值是一个指针int*
形参是int
int *(*pfun)(int)
//这个是一个函数指针,指向返回值是一个指针int*
形参是int
这种类型的函数 如果这个理解了
把int*换成你例子中的vector<int>*
,他俩是一样的
实际运用:
bool seq_elem(int pos,int &elem,const vector<int>*(*seq_ptr)(int))
{
//调用seq_ptr所指的函数
const vector<int> *pseq=seq_ptr(pos);
if(!pseq)
{
elem=0;
return false;
}
elem=(*pseq)[pos-1];
}
请看,由函数指针指向的函数,其调用方式和一般函数相同。那个指针赋值的代码就相当于调用了seq_ptr所指的函数。(你可能会有疑问,那个(pos)是什么为什么要加上来。实际上seq_ptr是指针,他的数据类型(当然,他也得有和指向的函数相同的参表)必须要和指向的函数匹配才可以!)
那个if语句,是用来间接检验指针seq_ptr((*seq_ptr)(int)
)有没有指向一个函数。我们必须做这个检验!你也可以直接检验seq_ptr这个指针,如下
if(!seq_ptr)
{
display_messsage("seq_ptr is set to null!");
}
- 可以给函数指针赋初值,如下
const vector<int>* (*seq_ptr)(int)=0;
指针初值为0,表示没有指向任何函数
seq_ptr=pell_seq;
这是把pell_seq()的地址赋值给函数指针seq_ptr(可以拿某个函数的地址作为函数指针的初值)
- 你也可以定义个函数指针数组,如下
const vector<int>*(*seq_array[])(int)={fibon_seq,lucas_seq,pell_seq,triang_seq,square_seq,pent_seq};
解释一下,seq_array是由六个函数指针的数组,数组第一个元素指向fibon_seq(),第二个元素指向lucas_seq(),以此类推。
可以选择迭代,这样可以在间接调用每个函数。如下
const vector<int>*(*seq_array[])(int)={fibon_seq,lucas_seq,pell_seq,triang_seq,square_seq,pent_seq};
//为了方便看代码我把数组给写下来了
bool seq_elem(int pos,int &elem,const vector<int>*(*seq_ptr)(int))
{
int seq_index=0;
while(next_seq==true)
{
seq_ptr=seq_array[++seq_index];
//...
}
}
当seq_ptr=seq_array[1]时,那么seq_ptr这个函数指针就被赋予lucas_seq()函数的地址,即seq_ptr=lucas_seq;seq_ptr指向了lucas_seq()函数
- 但是,你可能记不住那么多函数名的下标是几,所以你可以定义枚举类型,来帮助你方便调用(索引)那些函数。(为什么要学枚举类型)
枚举类型:关键字enum,之后空格,然后写一个标识符(不写也行),我举一个例子来说明该类型:
enum ns_type{ ns_fibon,ns_lucas,ns_pell,ns_triang,ns_square,ns_pent};
其中每个项被称为枚举项,默认情况下,第一个枚举项的值为0,后面的每个枚举项的值都比前面的多1,也就是说第二个枚举项的值为1,第三个为2,以此类推,我们可以得出,ns_pent的值为5
我们可以使用通过对应的枚举项来作为数组索引值,以这样的方式取用函数指针。
seq_ptr=seq_array[ns_pell];
但是你不要写[5],因为枚举类型是枚举类型而不是数组,枚举类型比数组的优点是你不用考虑对应下标,你直接写一个名字到[]里就可以了,省下大脑的计算工作。
关于枚举类型的其他具体用法,自行百度。