【C语言】用回调函数实现冒泡排序
(一)什么是回調(diào)函數(shù)呢?
- 回調(diào)函數(shù)就是通過(guò)函數(shù)指針調(diào)用的函數(shù)。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個(gè)函數(shù),當(dāng)這個(gè)指針被用為調(diào)用它所指向的函數(shù)時(shí),我們就說(shuō)這是回調(diào)函數(shù)。
(二)回調(diào)函數(shù)的實(shí)現(xiàn)機(jī)制
1.定義一個(gè)回調(diào)函數(shù)
2.提供函數(shù)實(shí)現(xiàn)的一方在初始化時(shí)。將回調(diào)函數(shù)的函數(shù)指針注冊(cè)給調(diào)用者。
3.當(dāng)特定的條件發(fā)生時(shí),調(diào)用者使用函數(shù)指針調(diào)用回調(diào)函數(shù)對(duì)事件進(jìn)行處理。
(三)回調(diào)函數(shù)的使用原因
- 通過(guò)回調(diào)函數(shù),可以將調(diào)用者與被調(diào)用者分開。
可能你不知道,在庫(kù)函數(shù)中有一個(gè)qsort函數(shù),即我們通常說(shuō)的快速排序,讓我們看它是如何調(diào)用和實(shí)現(xiàn)的。
- 原型:void qsort( void *base, size_t num, size_t width, int (__cdecl *compare ) (const void *elem1, const void *elem2 ) )
base:目標(biāo)數(shù)組的首位置
num:元素個(gè)數(shù)
width:每個(gè)元素所占字節(jié)數(shù)
compare:函數(shù)指針,指向一個(gè)比較函數(shù)
qsort實(shí)現(xiàn):
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> #include<string.h>int compare_int(const void *elem1,const void *elem2)//排序整型數(shù)組 {return *(int *)elem1-*(int *)elem2; }int compare_float(const void *elem1,const void *elem2)//排序浮點(diǎn)型數(shù)組 {if((*(float *)elem1)-(*(float *)elem2) > 0)//不可以直接返回二者的差,轉(zhuǎn)化為整型時(shí)可能漏掉部分?jǐn)?shù)據(jù) return 1;else if((*(float *)elem1)-(*(float *)elem2) == 0)return 0;elsereturn -1; }int compare_string(const void *elem1,const void *elem2) {return strcmp(*(char **)elem1,*(char **)elem2);//應(yīng)先找到每個(gè)字符串的首地址再進(jìn)行解引用 }void print_int_arr(int arr[],int sz) {int i = 0;for(i=0; i<sz; i++){printf("%d ",arr[i]);}printf("\n"); } void print_float_arr(float arr[],int sz) {int i = 0;for(i=0; i<sz; i++){printf("%f ",arr[i]);}printf("\n"); } void print_string_arr(char **arr,int sz) {int i = 0;for(i=0; i<sz; i++){printf("%s ",arr[i]);}printf("\n"); } int main() {int arr1[]={2,4,6,8,0,1,3,5,7,9};int sz1 = sizeof(arr1)/sizeof(arr1[0]);float arr2[]={2.0f,4.4f,6.5f,8.3f,0.0f,1.2f,3.7f,5.6f,7.9f,9.8f};int sz2 = sizeof(arr2)/sizeof(arr2[0]);char *arr3[]={"abcd", "bbdd", "aabc", "dfer","dghjf"};int sz3 = sizeof(arr3)/sizeof(arr3[0]);qsort(arr1,sz1,sizeof(int),compare_int);qsort(arr2,sz2,sizeof(int),compare_float);qsort(arr3,sz3,sizeof(int),&compare_string);print_int_arr(arr1,sz1);print_float_arr(arr2,sz2);print_string_arr(arr3,sz3);system("pause");return 0; }
qsort()測(cè)驗(yàn)各種類型數(shù)據(jù)效果圖:
- 通過(guò)回調(diào)函數(shù),我們同時(shí)排序了不同類型的數(shù)組元素,是不是很方便呢,同時(shí)讓程序也更靈活了。
接下來(lái),我們?cè)囋嚹芊窠栌没卣{(diào)函數(shù)實(shí)現(xiàn)冒泡排序吧!
回調(diào)函數(shù)實(shí)現(xiàn)冒泡排序
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> #include<string.h>int compare_int(const void *elem1, const void *elem2) {return *(int *)elem1 - *(int *)elem2; }int compare_float(const void *elem1, const void *elem2) {//不可以直接返回二者的差,轉(zhuǎn)化為整型時(shí)可能漏掉部分?jǐn)?shù)據(jù) if ((*(float *)elem1) - (*(float *)elem2) > 0)return 1;else if ((*(float *)elem1) - (*(float *)elem2) == 0)return 0;elsereturn -1; }int compare_double(const void *elem1, const void *elem2) {//不可以直接返回二者的差,轉(zhuǎn)化為整型時(shí)可能漏掉部分?jǐn)?shù)據(jù) if ((*(double *)elem1) - (*(double *)elem2) > 0) return 1;else if ((*(double *)elem1) - (*(double *)elem2) == 0)return 0;elsereturn -1; }int compare_char(const void *elem1, const void *elem2) {//應(yīng)先找到每個(gè)字符串的首地址再進(jìn)行解引用return *(char *)elem1 - *(char *)elem2; }int compare_string(const void *elem1, const void *elem2) {//應(yīng)先找到每個(gè)字符串的首地址再進(jìn)行解引用return strcmp(*(char **)elem1, *(char **)elem2); }void Swap(size_t width, void *n1, void *n2) {char tmp = 0;size_t i = 0;for (i = 0; i<width; i++){tmp = *((char *)n1 + i);*((char *)n1 + i) = *((char *)n2 + i);*((char *)n2 + i) = tmp;} } void bubble_sort(void *base, size_t sz, size_t width,int(*compare)(const void*, const void*)) {size_t i = 0;size_t j = 0;for (i = 0; i<sz - 1; i++){for (j = 0; j<sz - 1 - i; j++){if (compare(((char*)base + j*width), ((char *)base + (j + 1)*width))>0)//升序//if(compare((char *)base+j*width),(char *)base+(j+1)*width)>0)//降序Swap(width, ((char *)base + j*width), ((char *)base + (j + 1)*width)); }} } void print_int_arr(int arr[], int sz) {int i = 0;for (i = 0; i<sz; i++){printf("%d ", arr[i]);}printf("\n"); } void print_float_arr(float arr[], int sz) {int i = 0;for (i = 0; i<sz; i++){printf("%f ", arr[i]);}printf("\n"); } void print_double_arr(double arr[], int sz) {int i = 0;for (i = 0; i<sz; i++){printf("%lf ", arr[i]);}printf("\n"); } void print_char_arr(char arr[], int sz) {int i = 0;for (i = 0; i<sz; i++){printf("%c ", arr[i]);}printf("\n"); } void print_string_arr(char *arr[], int sz) {int i = 0;for (i = 0; i<sz; i++){printf("%s ", arr[i]);}printf("\n"); } int main() {int arr1[] = { 2, 4, 6, 8, 0, 1, 3, 5, 7, 9 };int sz1 = sizeof(arr1) / sizeof(arr1[0]);float arr2[] = { 2.0f, 4.4f, 6.5f, 8.3f, 0.0f, 1.2f, 3.7f, 5.6f, 7.9f, 9.8f };int sz2 = sizeof(arr2) / sizeof(arr2[0]);double arr3[] = { 1.1, 2.4, 3.5, 4.6, 7.8, 9.0 };int sz3 = sizeof(arr3) / sizeof(arr3[0]);char arr4[] = { 'd', 'f', 'b', 'c', 'e', 'g', 'h', 'a' };int sz4 = sizeof(arr4) / sizeof(arr4[0]);char *arr5[] = { "abcd", "bbdd", "aabc", "dfer", "dghjf" };int sz5 = sizeof(arr5) / sizeof(arr5[0]);bubble_sort(arr1, sz1, sizeof(int), compare_int);bubble_sort(arr2, sz2, sizeof(float), compare_float);bubble_sort(arr3, sz3, sizeof(double), compare_double);bubble_sort(arr4, sz4, sizeof(char), compare_char);print_int_arr(arr1, sz1);print_float_arr(arr2, sz2);print_double_arr(arr3, sz3);print_char_arr(arr4, sz4);print_string_arr(arr5, sz5);system("pause");return 0; }
回調(diào)函數(shù)實(shí)現(xiàn)冒泡的效果圖
結(jié)語(yǔ)
能力往往不是一蹴而就的,憑借的是你不屈向上攀爬的動(dòng)力,如果你有意愿,我們一起努力!!!
總結(jié)
以上是生活随笔為你收集整理的【C语言】用回调函数实现冒泡排序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 面试70问经典回答技巧
- 下一篇: 62道开发人员面试经典题