網(wǎng)站首頁 編程語言 正文
C++函數(shù)指針詳細理解
函數(shù)指針初識
函數(shù)指針是指向函數(shù)的指針,并不等于函數(shù),它能夠執(zhí)行函數(shù)的操作,可以跟指針變量一起來理解,其基本聲明格式為:
type (*ptrname)(形參列表);
例子,聲明一個比較兩個字符串大小的函數(shù)指針
bool (*cp)(const string s1, const string s2);
需要注意的是,不要去掉括號!!!如果去掉括號,含義就變成了返回一個bool指針的函數(shù)的聲明!
函數(shù)指針指向函數(shù)類型
在使用函數(shù)指針時,函數(shù)指針可以發(fā)揮與函數(shù)相同的功效,即也可以起到執(zhí)行任務(wù)的作用,但是函數(shù)指針需要初始化,而且不存在函數(shù)指針類型的轉(zhuǎn)換,在進行初始化的時候,函數(shù)指針可以被賦值為
nullptr
或常量NULL
,或者指向一個函數(shù),但是,指向這個函數(shù)時,需要有嚴(yán)格的要求,它需要嚴(yán)格按照兩者的返回類型,形參列表相對應(yīng)
例子
// 兩個示例函數(shù) bool compareLength(const string s1, const string s2){ //當(dāng)s1的長度大于s2的長度,返回true,否則返回false return s1.size() > s2.size()?true:false; } int getLength(const string s1){ //返回字符串的長度 return s1.size(); } // 初始化前面定義的cp函數(shù)指針 cp = nullptr; // 正確,初始化為空 cp = NULL; // 正確,初始化為空常量NULL cp = compareLength; // 正確,函數(shù)的返回形式和形參列表和類型都是一樣的 cp = getLength; // 錯誤,返回類型和形參列表不一樣
使用函數(shù)
接著上面的思路,函數(shù)調(diào)用的方式可以這樣寫
// 函數(shù)指針調(diào)用函數(shù) cp(s1, s2); // 調(diào)用2 (*cp)(s1, s2); // 函數(shù)調(diào)用,與cp一樣 compareLength(s1, s2);
函數(shù)指針作為形參使用
可以將函數(shù)或者函數(shù)指針作為某一個函數(shù)的形式參數(shù)傳入并使用,如C++11的thread頭文件線程的構(gòu)造函數(shù)中急需要傳遞一個函數(shù)指針的實例
#include<thread> std::thread t(函數(shù)指針, ..Args);
其聲明定義形式如下,比如將上面定義的函數(shù)或函數(shù)指針傳入一個新的函數(shù)中,作為兩者的比較依據(jù)
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; } } // 或者以指針的形式來聲明函數(shù)形參, 這種定義與上面那種定義是等價的 int packageFunc(const string &s1, const string &s2, bool (*cp)(const string &, const string &));
考慮到這樣的形式參數(shù)聲明太過冗長,可以使用typedef和decltype來簡化操作,比如上面代碼又可以這樣寫
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)
或者定義成函數(shù)指針的形式
typedef bool (*fp)(const string &, const string &); int packageFunc(const string s1, const string s2, fp); // 定義成函數(shù)指針的形式,與上面的聲明等價 typedef decltype(compareLength) *fp_ptr; int packageFunc(const string s1, const string s2, fp_ptr);
或者還可以這樣寫
using fp = bool (*)(const string &, const string &);
typedef
:是自定義數(shù)據(jù)類型的聲名符,可以用于定義自己的數(shù)據(jù)類型,與using
有相似的地方
decltype
:它返回一個函數(shù)類型,即對傳入的函數(shù)類型進行處理,返回一個返回類型和形參定義都與傳入函數(shù)相等的函數(shù)類型,但是它無法將返回的函數(shù)類型自動轉(zhuǎn)變?yōu)楹瘮?shù)指針,所以再需要函數(shù)指針是要加*
號
函數(shù)指針作為返回值
函數(shù)指針也可作為返回值,比如傳統(tǒng)的Unix進程間通過signal通信的方式的signal
函數(shù)就會返回函數(shù)指針類型,如
#include<signal.h> 函數(shù)指針 = signal(SIGABRT, 函數(shù)句柄); // 其返回的就是一個函數(shù)指針,即上一個與這個信號綁定的函數(shù)句柄,如果是第一次綁定返回NULL
但是函數(shù)類型不可,依據(jù)上面的簡要聲明,
using F = int(int *, int); using PF = int (*)(int*, int); PF f1(int); // 正確,PF為指函數(shù)的指針 F f2(int); // 錯誤,F(xiàn)為函數(shù)類型 F* f3(int); // 正確,顯式的制定了函數(shù)返回函數(shù)指針的形式
也可以直接聲明,但是不太好理解,會導(dǎo)致代碼的可讀性差,不建議這樣做
int (*f1(int))(int*, int);
還可以以后置形式聲明一個函數(shù)返回一個函數(shù)指針類型
auto f1(int) -> int (*)(int*, int);
練習(xí)
編寫函數(shù)的聲明,令其接收兩個int形參并且返回類型也是int;然后聲明一個vector對象,零其元素執(zhí)行函數(shù)的指針
#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)); }
add:[10 + 5 = 5]sub:[10 - 5 = 5]
總結(jié)
原文鏈接:https://blog.csdn.net/qq_48201696/article/details/122335138
相關(guān)推薦
- 2022-07-26 使用Nginx+Tomcat實現(xiàn)負(fù)載均衡的全過程_nginx
- 2023-06-03 Numpy數(shù)值積分的實現(xiàn)_python
- 2022-09-09 React前端DOM常見Hook封裝示例下_React
- 2023-07-16 oracle 創(chuàng)建存儲過程
- 2023-07-15 React 中的 context使用方法
- 2023-01-18 React報錯Element?type?is?invalid解決案例_React
- 2022-08-01 React中的Hooks進階理解教程_React
- 2022-07-23 C++超詳細講解稀疏矩陣_C 語言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支