1. 回調函數是什么?
2. qsort使用舉例
3. qsort函數的模擬實現
1. 回調函數是什么?
回調函數就是?個通過函數指針調用的函數。
如果你把函數的指針(地址)作為參數傳遞給另?個函數,當這個指針被用來調用其所指向的函數
時,被調用的函數就是回調函數。回調函數不是由該函數的實現方直接用,而是在特定的事件或條 件發?時由另外的?方調用的,用于對該事件或條件進行響應。
我們寫的計算機的實現的代碼中,紅色框中的代碼是重復出現的,其中雖然執行計算的邏輯
是區別的,但是輸?輸出操作是冗余的,有沒有辦法,簡化?些呢?因為紅色框中的代碼,只有調用函數的邏輯是有差異的,我們可以把調?的函數的地址以參數的形式
傳遞過去,使用函數指針接收,函數指針指向什么函數就調用什么函數,這里其實使用的就是回調函數的功能。
使用回調函數改造前:
#include <stdio.h>
int add(int x, int y) {return x + y;
}
int sub(int x, int y) {return x - y;
}
int mul(int x, int y) {return x * y;
}
int div(int x, int y) {return x / y;
}
int main() {int x, y;int input = 0;int ret = 0;do {printf("*******************\n");printf("**1.add 2.sub**\n");printf("**3.mul 2.div**\n");printf("**0.退出程序 ****\n");printf("*******************\n");printf("請選擇:");scanf("%d", &input);switch (input) {case 1:printf("請輸入操作數:");scanf("%d %d", &x, &y);ret = add(x, y);printf("ret=%d\n", ret);case 2:printf("請輸入操作數:");scanf("%d %d", &x, &y);ret = sub(x, y);printf("ret=%d\n", ret);break;case 3:printf("請輸入操作數:");scanf("%d %d", &x, &y);ret = mul(x, y);printf("ret=%d\n", ret);break;case 4:printf("請輸入操作數:");scanf("%d %d", &x, &y);ret = div(x, y);printf("ret=%d\n", ret);break;case 0:printf("退出程序\n");break;default:printf("選擇錯誤\n");break;}} while (input);return 0;
}
運行效果:

?
使用回調函數改造后:?
#include <stdio.h>
int add(int x, int y) {return x + y;
}
int sub(int x, int y) {return x - y;
}
int mul(int x, int y) {return x * y;
}
int div(int x, int y) {return x / y;
}
void calc(int(*p)(int, int)) {int x, y;int ret = 0;printf("請輸入操作數:");scanf("%d %d", &x, &y);ret = p(x, y);printf("ret=%d\n", ret);
}
int main() {int input = 0;do {printf("*******************\n");printf("**1.add 2.sub**\n");printf("**3.mul 2.div**\n");printf("**0.退出程序 ****\n");printf("*******************\n");printf("請選擇:");scanf("%d", &input);switch (input) {case 1:calc(add);break;case 2:calc(sub);break;case 3:calc(mul);break;case 4:calc(div);break;case 0:printf("退出程序\n");break;default:printf("選擇錯誤\n");break;}} while (input);return 0;
}
運行效果:?
?2. qsort使用舉例
2.1 使用qsort函數排列整型數據
代碼實現:?
#include <stdio.h>
int int_cmp(const void* p1, const void* p2) {return(*(int*)p1 - *(int*)p2);
}
int main() {int arr[] = { 1,4,5,2,6,8,0,9,7,3 };int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), int_cmp);for (i = 0; i < sz; i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}
運行效果:?
2.2 使用qsort排序結構數據
這里需要補充介紹結構體和結構體成員訪問操作符"->";?
代碼實現:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct stu{char name[20];int age;
};
void print(struct stu arr[], int sz) {for (int i = 0; i < sz; i++) {printf("%s:%d ", arr[i].name, arr[i].age);}printf("\n");
}
int cmp_stu_age(const void* p1, const void* p2) {return (((struct stu*)p1)->age - ((struct stu*)p2)->age);
}
int cmp_stu_name(const void* p1, const void* p2) {
//strcmp - 是庫函數,是專??來?較兩個字符串的??的
//假設按照名字來?較return strcmp((((struct stu*)p1)->name) ,(((struct stu*)p2)->name));
}
//按年齡排序
void test1() {struct stu arr[] = { {"zhangsan",35},{"lisi",20},{"wangwu",18} };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_stu_age);print(arr, sz);
}
//按名字排序
void test2() {struct stu arr[] = { {"zhangsan",35},{"lisi",20},{"wangwu",18} };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_stu_name);print(arr, sz);
}
int main() {test1();test2();return 0;
}
運行效果:?
?3. qsort函數的模擬實現
用回調函數,模擬實現qsort(采用冒泡的?式)。
注意:這里第?次使?用void* 的指針,講解 void* 的作用。
?
?代碼實現:
#include <stdio.h>
int int_cmp(const void* p1, const void* p2)
{return (*(int*)p1 - *(int*)p2);
}
void _swap(void* p1, void* p2, int size)
{int i = 0;for (i = 0; i < size; i++){char tmp = *((char*)p1 + i);*((char*)p1 + i) = *((char*)p2 + i);*((char*)p2 + i) = tmp;}
}
void bubble(void* base, int count, int size, int(*cmp)(void*, void*))
{int i = 0;int j = 0;for (i = 0; i < count - 1; i++){for (j = 0; j < count - i - 1; j++){if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) >0){_swap((char*)base + j * size, (char*)base + (j + 1) * size,size);}}}
}
int main()
{int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };int i = 0;bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++){printf("%d ", arr[i]);}printf("\n");return 0;
}
運行效果:

完。?