網站首頁 編程語言 正文
函數指針
以下是
void qsort (void* base, size_t num, size_t size, int (*compar)(const void*, const void*));
-
base
?-- 指向要排序的數組的第一個元素的指針。 -
num
-- 由 base 指向的數組中元素的個數。 -
size?
-- 數組中每個元素的大小,以字節為單位。 -
compar
?-- 用來比較兩個元素的函數。
對于可以使用常規關系運算符進行比較的類型,常規比較函數可能如下所示:
int compareMyType (const void * a, const void * b) { if ( *(MyType*)a < *(MyType*)b ) return -1; if ( *(MyType*)a == *(MyType*)b ) return 0; if ( *(MyType*)a > *(MyType*)b ) return 1; }
#include#include int cmpfunc (const void* a, const void* b); using namespace std; int main() { int values[] = { 88, 56, 100, 2, 25 }; qsort(values, sizeof(values)/sizeof(int), sizeof(int), cmpfunc); cout << "排序之后的列表:" << endl; for(int n = 0 ; n < 5; n++ ) { cout << values[n] << " "; } return 0; } int cmpfunc (const void* a, const void* b) { return ( *(int*)a - *(int*)b ); }
Enter a string (empty line to quit):|abcEnter menu choice: u) uppercase l) lowercase t) transposed case o) original case n) next string Please enter u, l, t, o, or n: |u ABC Enter menu choice: u) uppercase l) lowercase t) transposed case o) original case n) next string Please enter u, l, t, o, or n: |l abc
#include#include #include #include #include #define LEN 81 char showmenu(); void show(void (* fp)(char*), char* str); void ToUpper(char*); // 把字符串轉換為大寫 void ToLower(char*); // 把字符串轉換為小寫 void Transpose(char*); // 大小寫轉置 void Dummy(char*); // 不更改字符串 using namespace std; int main() { char line[LEN]; char copy[LEN]; char choice; void (* pfun)(char*); // 聲明一個函數指針, 被指向的函數接受char *類型的參數, 無返回值 cout << "Enter a string (empty line to quit):"; while (cin >> line) { while ((choice = showmenu()) != 'n') { switch (choice) { // switch語句設置指針 case 'u': pfun = ToUpper; break; case 'l': pfun = ToLower; break; case 't': pfun = Transpose; break; case 'o': pfun = Dummy; break; } strcpy(copy, line); // 為show()函數拷貝一份 show(pfun, copy); // 根據用戶的選擇, 使用選定的函數 } cout << "Enter a string (empty line to quit):"; } cout << "Bye!"; return 0; } char showmenu() { char ans; cout << "Enter menu choice:" << endl; cout << "u) uppercase l) lowercase" << endl; cout << "t) transposed case o) original case" << endl; cout << "n) next string" << endl; ans = getchar(); // 獲取用戶的輸入 ans = tolower(ans); // 轉換為小寫 while (strchr("ulton", ans) == NULL) { cout << "Please enter u, l, t, o, or n:" << endl; ans = tolower(getchar()); } return ans; } void show(void (* fp)(char*), char* str) { (*fp)(str); // 把用戶選定的函數作用于str cout << str << endl; // 顯示結果 } void ToUpper(char* str) { while (*str) { *str = toupper(*str); str++; } } void ToLower(char* str) { while (*str) { *str = tolower(*str); str++; } } void Transpose(char* str) { while (*str) { if (islower(*str)) *str = toupper(*str); else if (isupper(*str)) *str = tolower(*str); str++; } } void Dummy(char* str) { } //不改變字符串
函數對象
函數對象是專門設計用于語法與函數相似的對象。在C++中,這是通過在類中定義成員函數operator()
來實現的,例如:
struct myclass { int operator()(int a) { return a; } } myobject; int x = myobject(0);
它們通常用作函數的參數,例如傳遞給標準算法的謂詞或比較函數。
標準庫預先定義了些function object。所謂function object
,是某種class的實例對象,這類class對function call運算符做了重載操作,如此一來可使function object被當成一般函數來使用。
function object實現了我們原本可能以獨立函數加以定義的事物。但又何必如此呢?
主要是為了效率。我們可以令call運算符成為inline,從而消除“通過函數指針來調用函數”時需要付出的額外代價。
標準庫事先定義了一組function object
,分為:
算術運算(arithmetic
)、關系運算(relational
)和邏輯運算(logical
)三大類。
以下列表中的type在實際使用時會替換為內置類型或class類型:
6個算術運算 |
plus multiplies |
6個關系運算 |
less greater_equal |
3個邏輯運算 | logical_and |
要使用事先定義的function object,首先得包含相關頭文件:<functional
>
默認情況下sort()是升序排列,我們將元素降序排列:
sort(vec.begin(), vec.end(), greater());
其中的greater
binary_search()期望其搜索對象先經過排序,為了正確搜索vector,就必須傳給它某個function object object
,供vector排序使用:
binary_search(vec.begin(), vec.end(), elem, greater());
我們對Fibonacci數列可以做些其他操作,如:每個元素和自身相加、和自身相乘、被加到對應的Pell數列等等。做法之一是使用泛型算法transform()并搭配plus
我們必須傳給transform()的參數有:
?一對iterator,標示出欲轉換的元素范圍;
?一個iterator,所指元素將應用于轉換上,元素范圍同?;
?一個iterator,所指位置(及其后面的空間)用來存放轉換結果;
?一個function object,表現出我們想要應用的轉換操作。
以下是將Pell數列加到Fibonacci數列的寫法:
transform(fib.begin(), fib.end(), //? pell.begin(), //? fib_plus_pell.begin(), //? plus); //?
transform()的定義:
function template std::transform
unary operation(1) templateOutputIterator transform(InputIterator first1, InputIterator last1, OutputIterator result, UnaryOperation op); binary operation(2) template OutputIterator transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryOperation binary_op); ———————————————————————————————————————————————————— 將操作順序應用于一(1)或兩(2)個范圍的元素,并將結果存儲在從結果開始的范圍中。 (1) 一元操作 將op應用于[first1,last1]范圍內的每個元素,并將每個操作返回的值存儲在從result開始的范圍內。 (2) 二元操作 使用范圍[first1,last1]中的每個元素作為第一個參數,并使用范圍中從first2開始的各個參數作為 第二個參數來調用binary_op。每個調用返回的值存儲在從result開始的范圍中。 該函數允許目標范圍與其中一個輸入范圍相同,以便進行適當的轉換。
函數對象適配器:
function object less
真的可以做到這樣嗎?是的。標準庫提供adapter(適配器)便應此而生。
function object adapter會對function object進行修改操作。binder adapter(綁定適配器)會將function object的參數綁定至某特定值,使binary(二元) function object轉化為unary(一元)function object。這正是我們需要的。
標準庫提供了兩個binder adapter
:
bind1st
會將指定值綁定至第一操作數;
bind2nd
將指定值綁定至第二操作數。
如:a < b,則a是第一操作數,b是第二操作數。
vectorfilter &vec, int val, less <) { vector nvec; vector ::const_iterator iter = vec.begin(); while ((iter = find_if(iter, vec.end(), bind2nd(lt, val))) != vec.end()) { nvec.push_back(*iter); iter++; } return nvec; }
下面看一個泛型函數find_if()的例子: 看一個bind2nd()和bind1st()的例子:bind2nd(less, val)
;會把val綁定于lessfind_if()
的定義如下:template
#include
The first odd value is 25
#include
There are 3 negative elements.
#include
There are 2 positive elements.
總結
原文鏈接:https://blog.csdn.net/itzyjr/article/details/123618936
相關推薦
- 2022-10-10 YOLOv5改進之添加SE注意力機制的詳細過程_python
- 2022-08-07 Android?實現自定義折線圖控件_Android
- 2022-08-29 Oracle中日期的使用方法實例_oracle
- 2022-05-13 C++ 使用Poco庫實現XML的讀取和寫入
- 2022-06-06 前端怎么把px單位換成rem單位解決項目頁面適配問題
- 2022-05-24 C#?連接本地數據庫的實現示例_C#教程
- 2022-07-11 Could not transfer artifact org.springframework.bo
- 2022-08-12 Pandas中DataFrame常用操作指南_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支