本文並不是將什麼是指標函數,不過通過本文會令你對指標函數理解更深。
對於C++裡面的排序函數qsort大家並不陌生。由於排序在電腦系統中的大量使用,各種程式設計語言都提供了相應的模板或泛型。因為排序只是一種順序上面的變化,並不會影響資料本身。所以不關乎什麼類型的資料排序,重要的是排序演算法本身。快速排序的平均效率較高。適合大部分的排序情況。在這裡,將通過講解qsort函數來學習指標函數的使用。
函數原型:void qsort(void *base, int nelem, int width, int (*fcmp)(const void *,const void *))
參數:
base:指向void類型的指標。其實是指向待排序數組的首地址。
nelem:待排序數組元素的個數。
width:每個元素所佔儲存空間的大小,多少個位元組?多用sizeof來計算。
fcmp:用於對數組元素進行比較的函數指標。重點就在這裡。
分析:
1.fcmp是一個函數指標,指向一個比較函數compare,compare函數是由我們自己來實現,告訴qsort什麼是“先”什麼是“後”,或者叫什麼是“大”什麼是“小”,由於排序總是基於量元素比較的基礎上的。你通過實現compare比較函數告訴qsort哪個放在前,哪個放在後。那麼qsort就會按照你的指示來完成排序。
2.由於fcmp被聲明為int (*fcmp)(const void *,const void *)。所以我們在定義比較函數為fcmp賦值時就要遵照這一參數規則。舉個例子:
int compare(const void *str1, const void *str2){char *s1 = (char*)str1;char *s2 = (char*)str2;if(*s1 < *s2)return -1;else if(*s1 > *s2)return 1;return 0;}(1)傳回值為-1,表示第一個參數“小於”第二個參數,或者說第一個要排在第二個前面。
(2)傳回值為1,表示第一個參數“大於”第二個參數,或者說第一個要排在第二個後面。
(3)傳回值為0.表相等。
所以如果你需要降序,應該知道怎麼改吧?
3.總結一下,其實就是在調用qsort為其排序的時候,可以告訴qsort如何決定兩個元素的先後順序,就是利用函數指標這一手法。這也就是傳說中的回調!相當於我們去飯店吃飯,本來是我們調用飯店做菜即可,但是,我們還要做的就是給人家把菜單寫好,人家才可以執行做菜。這種手法應用非常普遍的。當物件導向程式設計產生以後,這個問題就很容易解決了。
舉個例子,對字串數組排序
#include<iostream>#include<cstring>#include<algorithm>using namespace std;int strcmp(const void *str1, const void *str2){char *s1 = (char*)str1;char *s2 = (char*)str2;for(s1, s2; *s1 != '\0' && *s2 != '\0'; s1++, s2++){if(*s1 < *s2){return -1;}else if(*s2 < *s1){return 1;}}if(strlen(s1) < strlen(s2)){return -1;}else if(strlen(s2) < strlen(s1)){return 1;}return 0;}int main(){//freopen("test.txt", "r", stdin);int n = 0;while(cin >> n){char str[25][101];int i = 0;for(i = 0; i < n; i++){cin >> str[i];}qsort(str, n, sizeof(char) * 101, strcmp);for(i = 0; i < n; i++){cout << str[i] << endl;}}return 0;}