今天上課的時候,老師給我們詳細的講了函數指針的用法。記得大一的時候上C語言的時候,只知道有函數指針這個概念,但是后來都一直沒用到。但好像也有用到,每次在編程時,調用c庫的qsort函數的時候,可以看到qsort的最后一個參數就是個函數指針,但是當時都不怎么的在意,就知道怎么用就可以了。今天在老師系統的講之后,以后再遇到的話,應該就沒有問題!今天下課回來后,我也去翻了下《c專家編程》和《C和指針》這兩本書,發現C和指針里面在高級指針話題那章有講到函數指針,並且也講到了他們的應用----回調函數和轉移表。由於時間關系,下次再仔細的看看吧。不過我發現這兩本書還是非常的好!對於C語言的進階非常有幫助,沒事了可以翻一翻,看一看!
回歸正題吧,我們一般用冒泡函數都是對整型或者浮點型進行排序,但是如果我們遇到對字符的排序呢?為了讓我們的bubble-sort更具通用性,其實也是把bubble-sort封裝得更好些,也就是把它弄成跟qsort一樣~那么我們就可以聲明這樣一個函數:
void bubble_sort(void *arr[], int len,int (*cmp)(void *a, void *b));
根據要比較的數據類型的差異,我們可以傳入不同的比較函數給cmp這個函數指針,來實現不同類型的排序。然后我們會發現,為什么要聲明一個void *arr[],這是一個指針數組,什么是指針數組?首先它是一個數組,其次,它指向的是數組元素都是一個個指針,某個數據類型的地址(因為這里是void類型,所以可以轉換成各種類型)。比如int *arr[5]:
---------------------------------------------
| int * | int * | int * | int * | int * |
---------------------------------------------
如果要獲得它指向的類型的值,必須還需經過間接的*符號來獲取。
因為在程序中我們聲明了void *arr[9]這樣一個指針數組,那么我們在對不同的數據輸入的時候,就必須先給它開辟相應類型的空間來存儲。涉及到 指針數組的時候,操作起來就沒那么簡單了,如果真正把這個給理解並實現的話,那么對指針的理解將會是更深刻。
下面是我重新參照老師的算法實現的代碼,如果是針對字符或者浮點型的比較,那么我們可以只在輸入的地方稍微再做些修改,或者我們可以把輸入也封裝成一個函數,那就更方便了:
#include <stdio.h> #include <stdlib.h> int int_cmp(void *a, void *b); int char_cmp(void *a, void *b); void swap(void *arr, int a, int b); void bubble_sort(void *arr[], int len,int (*cmp)(void *a, void *b)); int main() { int len = 9,i; void *arr[9]; //void 類型的數組指針 for (i = 0; i < len; i++) { arr[i] =(int *)malloc(sizeof(int)); scanf("%d",(int *)arr[i]); } bubble_sort(arr,len,int_cmp); for (i = 0; i < len; i++) { printf("%d ",*(int *)arr[i]); } printf("\n"); free(arr); return 0; } int int_cmp(void *a, void *b) { return *(int *)a > *(int *)b ? 1:0; } void swap(void *arr[], int a, int b) { void *tmp; tmp = arr[a]; arr[a] = arr[b]; arr[b] = tmp; } void bubble_sort(void *arr[], int len,int (*cmp)(void *a, void *b)) { int i,j; for (i = 0; i < len-1; i++) { for (j = 0; j < len-i-1; j++) { if (cmp(arr[j],arr[j+1])) swap(arr,j,j+1); } } } 2013/10/11 22:02