服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++函数指针的用法详解

C++函数指针的用法详解

2022-08-13 10:59问号小朋友 C/C++

这篇文章主要为大家介绍了C++函数指针的用法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

C++函数指针详细理解

函数指针初识

函数指针是指向函数的指针,并不等于函数,它能够执行函数的操作,可以跟指针变量一起来理解,其基本声明格式为:

?
1
type (*ptrname)(形参列表);

例子,声明一个比较两个字符串大小的函数指针

?
1
bool (*cp)(const string s1, const string s2);

需要注意的是,不要去掉括号!!!如果去掉括号,含义就变成了返回一个bool指针的函数的声明!

函数指针指向函数类型

在使用函数指针时,函数指针可以发挥与函数相同的功效,即也可以起到执行任务的作用,但是函数指针需要初始化,而且不存在函数指针类型的转换,在进行初始化的时候,函数指针可以被赋值为nullptr或常量NULL,或者指向一个函数,但是,指向这个函数时,需要有严格的要求,它需要严格按照两者的返回类型,形参列表相对应

例子

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 两个示例函数
bool compareLength(const string s1, const string s2){
    //当s1的长度大于s2的长度,返回true,否则返回false
    return s1.size() > s2.size()?true:false;
}
 
int getLength(const string s1){
    //返回字符串的长度
    return s1.size();
}
 
// 初始化前面定义的cp函数指针
cp = nullptr;  // 正确,初始化为空
cp = NULL;     // 正确,初始化为空常量NULL
cp = compareLength;  // 正确,函数的返回形式和形参列表和类型都是一样的
cp = getLength;      // 错误,返回类型和形参列表不一样

使用函数

接着上面的思路,函数调用的方式可以这样写

?
1
2
3
4
5
6
7
8
// 函数指针调用函数
cp(s1, s2);
 
// 调用2
(*cp)(s1, s2);
 
// 函数调用,与cp一样
compareLength(s1, s2);

函数指针作为形参使用

可以将函数或者函数指针作为某一个函数的形式参数传入并使用,如C++11的thread头文件线程的构造函数中急需要传递一个函数指针的实例

?
1
2
3
#include<thread>
 
std::thread t(函数指针, ..Args);

其声明定义形式如下,比如将上面定义的函数或函数指针传入一个新的函数中,作为两者的比较依据

?
1
2
3
4
5
6
7
8
9
10
int packageFunc(const string &s1, const string &s2, bool comp(const string &s1, const string &s2)){
    if(comp(s1, s2)){
        cout<<"Yes"<<endl;
    }else{
        cout<<"No"<<endl;
    }
}
 
// 或者以指针的形式来声明函数形参, 这种定义与上面那种定义是等价的
int packageFunc(const string &s1, const string &s2, bool (*cp)(const string &, const string &));

考虑到这样的形式参数声明太过冗长,可以使用typedef和decltype来简化操作,比如上面代码又可以这样写

?
1
2
3
4
5
6
typedef bool Func(const string&, const string&);
int packageFunc(const string &s1, const string &s1, Func);
 
// 或者写成这样,这条语句与上面的typedef声明语句等价
typedef decltype(compareLength) Func2;
int packageFunc(const string &s1, const string &s1, Func2)

或者定义成函数指针的形式

?
1
2
3
4
5
6
typedef bool (*fp)(const string &, const string &);
int packageFunc(const string s1, const string s2, fp);
 
// 定义成函数指针的形式,与上面的声明等价
typedef decltype(compareLength) *fp_ptr;
int packageFunc(const string s1, const string s2, fp_ptr);

或者还可以这样写

?
1
using fp = bool (*)(const string &, const string &);

typedef:是自定义数据类型的声名符,可以用于定义自己的数据类型,与using有相似的地方

decltype:它返回一个函数类型,即对传入的函数类型进行处理,返回一个返回类型和形参定义都与传入函数相等的函数类型,但是它无法将返回的函数类型自动转变为函数指针,所以再需要函数指针是要加*

函数指针作为返回值

函数指针也可作为返回值,比如传统的Unix进程间通过signal通信的方式的signal函数就会返回函数指针类型,如

?
1
2
3
4
#include<signal.h>
 
函数指针 = signal(SIGABRT, 函数句柄);
// 其返回的就是一个函数指针,即上一个与这个信号绑定的函数句柄,如果是第一次绑定返回NULL

但是函数类型不可,依据上面的简要声明,

?
1
2
3
4
5
6
using F = int(int *, int);
using PF = int (*)(int*, int);
 
PF f1(int); // 正确,PF为指函数的指针
F  f2(int); // 错误,F为函数类型
F* f3(int); // 正确,显式的制定了函数返回函数指针的形式

也可以直接声明,但是不太好理解,会导致代码的可读性差,不建议这样做

?
1
int (*f1(int))(int*, int);

还可以以后置形式声明一个函数返回一个函数指针类型

?
1
auto f1(int) -> int (*)(int*, int);

练习

编写函数的声明,令其接收两个int形参并且返回类型也是int;然后声明一个vector对象,零其元素执行函数的指针

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<iostream>
#include<vector>
 
using namespace std;
 
int func1(int a, int b){
    // 加法
    return a+b;
}
 
int func2(int a, int b){
    // 减法
    return a - b;
}
 
int main(int argc, char *argv[]){
    decltype(func1) *p1 = func1, *p2 = func2;
    vector<decltype(func1)*> s = {p1,p2};
    int a = 10,b = 5;
    printf("add:[%d + %d = %d]\n", a, b, s[1](a,b));
    printf("sub:[%d - %d = %d]\n", a, b, s[1](a,b));
}
?
1
add:[10 + 5 = 5]sub:[10 - 5 = 5]

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注服务器之家的更多内容!

原文链接:https://blog.csdn.net/qq_48201696/article/details/122335138

延伸 · 阅读

精彩推荐
  • C/C++C++自定义API函数实现大数相乘算法

    C++自定义API函数实现大数相乘算法

    这篇文章主要为大家详细介绍了C++自定义API函数实现大数相乘算法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    Adamearth10142021-08-02
  • C/C++如何判断一个数是否为4的幂次方?若是,并判断出来是多少次方?

    如何判断一个数是否为4的幂次方?若是,并判断出来是多少次方

    本篇文章是对如何判断一个数是否为4的幂次方?若是,并判断出来是多少次方的实现方法,进行了详细的分析介绍,需要的朋友参考下...

    C语言教程网5962020-12-04
  • C/C++VScode配置C++运行环境的完整步骤

    VScode配置C++运行环境的完整步骤

    这篇文章主要给大家介绍了关于VScode配置C++运行环境的完整步骤,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    鱼大鹿10122021-10-18
  • C/C++C/C++中派生类访问属性详解及其作用介绍

    C/C++中派生类访问属性详解及其作用介绍

    这篇文章主要介绍了C/C++中派生类访问属性详解及其作用介绍,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可...

    我是小白呀3672021-12-30
  • C/C++C语言打印各种图案实例代码

    C语言打印各种图案实例代码

    大家好,本篇文章主要讲的是C语言打印各种图案实例代码,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览...

    weixin_5058896411822022-07-24
  • C/C++用C语言实现2048游戏

    用C语言实现2048游戏

    这篇文章主要为大家详细介绍了用C语言实现2048游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    he海ng8802021-12-06
  • C/C++C语言直接插入排序算法介绍

    C语言直接插入排序算法介绍

    大家好,本篇文章主要讲的是C语言直接插入排序算法介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览...

    绅士·永6382022-07-21
  • C/C++C++中replace() 函数的基本用法

    C++中replace() 函数的基本用法

    今天就跟大家聊聊有关C++中replace()函数的作用是什么,可能很多人都不太了解,为了让大家更加了解,这篇文章主要给大家介绍了关于C++中replace() 函数的基本用...

    cai_niaocainiao11692022-03-07