目錄
??編輯
1.回調函數的介紹
2. 回調函數實現轉移表
3. 冒泡排序的實現
4. qsort的介紹和使用
5. qsort的模擬實現?
6. 完結散花
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ?悟已往之不諫,知來者猶可追 ?
創作不易,寶子們!如果這篇文章對你們有幫助的話,別忘了給個免費的贊喲~
1.回調函數的介紹
這里首先介紹一下回調函數的概念~
回調函數是使用函數指針(地址)調用的函數。
如果我們把一個函數的指針(地址)作為一個參數傳遞給另一個函數,當我們通過指針找到這個函數并對其進行調用時,這個被調用的函數就是回調函數。
回調函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外的一方調用的,用于對該事件或條件進行響應
#include<stdio.h> test(void (*print)()) {print(); } void print() {printf("這是一個回調函數\n"); } int main() {test(print);return 0; }
2. 回調函數實現轉移表
現在我們來實現一個簡單的計算器~
#include <stdio.h> int add(int a, int b) { return a + b; } int sub(int a, int b) { return a - b; } int mul(int a, int b) { return a * b; } int div(int a, int b) { return a / b; } int main() { int x, y; int input = 1; int ret = 0; do { printf("*************************\n"); printf(" 1:add 2:sub \n"); printf(" 3:mul 4:div \n"); printf(" 0:exit \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); break; 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; }
我們可以很容易的觀察到上述代碼有一部分是多次重復的~
?這部分只有函數的調用是不一樣的,所以我們是不是可以把這部分封裝成一個函數calc(),在calc函數中調用不同的加減乘除函數就行了呢~
#include <stdio.h> int add(int a, int b) {return a + b; } int sub(int a, int b) {return a - b; } int mul(int a, int b) {return a * b; } int div(int a, int b) {return a / b; } void cacl(int(*p)(int x, int y)) {int x = 0;int y = 0;printf("輸入操作數:");scanf("%d %d", &x, &y);int ret = p(x, y);printf("ret = %d\n", ret); }int main() {int input = 1;do{printf("*************************\n");printf(" 1:add 2:sub \n");printf(" 3:mul 4:div \n");printf(" 0:exit \n");printf("*************************\n");printf("請選擇:");scanf("%d", &input);switch (input){case 1:cacl(add);break;case 2:cacl(sub);break;case 3:cacl(mul);break;case 4:cacl(div);break;case 0:printf("退出程序\n");break;default:printf("選擇錯誤\n");break;}} while (input);return 0; }
3. 冒泡排序的實現
常見的排序有插入排序、選擇排序、希爾排序、冒泡排序、快速排序等等~
在講qsort前,這里我們先了解一下冒泡排序~
顧名思義,冒泡排序就是讓元素像泡泡一樣慢慢往上移動~
?這里我用C語言來實現一下~
void bull_sort(int* arr,int len) {assert(arr);//判斷指針的有效性for (int i = 0; i < len - 1; i++){int flag = 1;//假設已經有序for (int j = 0; j < len - 1 - i; j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;flag = 0;}}if (flag == 1)break;} } int main() {int arr[] = { 9,8,7,6,5,4,3,2,1,0 };int len = sizeof(arr) / sizeof(arr[0]);bull_sort(arr, len);for (int i = 0; i < len; i++){printf("%d ", arr[i]);}return 0; }
運行效果~
?
4. qsort的介紹和使用
接下來我們就來看看qsort啦~
注意我們在使用qsort時要引入頭文件#include<stdlib.h>
這里簡單的舉個栗子來使用一下qsort啦~
int cmp_int(const void* a, const void* b) {assert(a && b);return *(int*)a - *(int*)b; } int main() {int arr[] = { 9,8,7,6,5,4,3,2,1,0 };int len = sizeof(arr) / sizeof(arr[0]);assert(arr);//判斷指針的有效性qsort(arr, len, sizeof(arr[0]), cmp_int);for (int i = 0; i < len; i++){printf("%d ", arr[i]);}return 0;; }
效果如下~
?我們還可以使用qsort比較結構體類型的變量!
我們通過結構體中的名字來比較結構體變量的大小~
struct S {char name[20];int age; };//定義一個結構體類型 int cmp_stu_by_age(const void* a,const void* b) {return strcmp(((struct S*)a)->name, ((struct S*)b)->name); } int main() {struct S student[3] = { {"zhangsan",18},{"lisi",17},{"wanglaowu",16} };//定義一個結構體數組并初始化int len = sizeof(student) / sizeof(student[0]);qsort(student, len, sizeof(student[0]), cmp_stu_by_age);return 0; }
排序前~
排序后~
5. qsort的模擬實現?
對比上面我們自己寫的冒泡排序和C語言中的內置快排,我們會發現我們自己寫的冒泡排序只能對int類型的數據進行排序(有局限性),而qsort卻可以對任意類型的數據進行排序。
接下來這里我就使用冒泡排序的算法模擬實現qsort~
int cmp_int(const void* a, const void* b) {assert(a && b);return *(int*)a - *(int*)b; } void swap(char* buf1,char* buf2,size_t num)//一個一個字節交換 {while (num--){char tmp = *(buf1);*(buf1) = *(buf2);*(buf2) = tmp;buf1++;buf2++;} } void my_qsort(void* arr, size_t len, size_t num, int (*cmp_int)(const void*,const void*)) {assert(arr);//判斷指針的有效性for (int i = 0; i < len - 1; i++){int flag = 1;//假設已經有序for (int j = 0; j < len - 1 - i; j++){if(cmp_int((char*)arr + j * num, (char*)arr + (j + 1) * num)>0);{swap(((char*)arr + j * num), ((char*)arr + (j + 1) * num),num);flag = 0;}}if (flag == 1)break;} } int main() {int arr[] = { 9,8,7,6,5,4,3,2,1,0 };size_t len = sizeof(arr) / sizeof(arr[0]);my_qsort(arr, len, sizeof(arr[0]), cmp_int);for (int i = 0; i < len; i++){printf("%d ", arr[i]);}return 0; }
運行效果如下~
?
6. 完結散花
好了,這期的分享到這里就結束了~
如果這篇博客對你有幫助的話,可以用你們的小手指點一個免費的贊并收藏起來喲~
如果期待博主下期內容的話,可以點點關注,避免找不到我了呢~
我們下期不見不散~~