網站首頁 編程語言 正文
前言
回調函數就是一個通過函數指針調用的函數。如果你把函數的指針(地址)作為參數傳遞給另一個函數,當這個指針被用來調用其所指向的函數時,我們就說這是回調函數。回調函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外的一方調用的,用于對該事件或條件進行響應。
今天用一個簡易的計算器和qsort的實現,帶大家深入了解回調函數
一、計算器
寫一個計算器、加法、減法、乘法、除法
1.switch語句實現
#include<stdio.h>
#include<string.h>
void menu()
{
printf("****************************\n");
printf("***** 1.add 2.sub ******\n");
printf("***** 3.mul 4.div ******\n");
printf("***** 0.exit ******\n");
printf("****************************\n");
}
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 input = 0;
int x = 0;
int y = 0;
int ret = 0;
do
{
menu();
printf("請選擇:>");
scanf("%d", &input);
printf("請輸入兩個操作數:>");
scanf("%d %d", &x, &y);
switch (input)
{
case 1:
ret = add(x, y);
printf("%d\n", ret);
break;
case 2:
ret = sub(x, y);
printf("%d\n", ret);
break;
case 3:
ret = mul(x, y);
printf("%d\n", ret);
break;
case 4:
ret = div(x, y);
printf("%d\n", ret);
break;
case 0:
printf("退出計算器\n");
break;
default:
printf("選擇錯誤\n");
break;
}
} while (input);
return 0;
}
2.回調函數實現
把加減乘除函數,封裝成一個函數指針calc,在用戶輸入需要什么功能時,只需要將函數的地址傳到回調函數中,大大的提高了代碼利用率,將功能封裝起來,高內聚低耦合。
#include<stdio.h>
#include<string.h>
void menu()
{
printf("****************************\n");
printf("***** 1.add 2.sub ******\n");
printf("***** 3.mul 4.div ******\n");
printf("***** 0.exit ******\n");
printf("****************************\n");
}
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 (*pf)(int, int))
{
int x = 0;
int y = 0;
int ret = 0;
printf("請輸入2個操作數:>");
scanf("%d %d", &x, &y);
ret = pf(x, y);
printf("%d\n", ret);
}
int main()
{
int input = 0;
do
{
menu();
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;
}
二、qsort
1.冒泡排序
在學習qsort之前先回顧一下冒泡排序
#include<stdio.h>
#include<string.h>
int main()
{
int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i < sz - 1; i++)
{
for (int j = 0; j < sz - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
int h = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = h;
}
}
}
for (i = 0; i < sz; i++) {
printf("%d ", arr[i]);
}
return 0;
}
2.qsort
相信很多小伙伴會有疑問,不是已經學習了冒泡排序,為什么還要學習qsort,不是多此一舉嗎?但是,冒泡排序只能排整形數據,那浮點數,字符型,結構體又該怎么實現呢,這就發揮出qsort的作用了。帶大家解讀一下qsort
3.qsort排序浮點數
#include<stdio.h>
#include<stdlib.h>
cmp_float(const void* e1, const void* e2)
{
return *(float*)e1 - *(float*)e2;
}
int main()
{
float f[] = { 5.0,4.0,3.0,2.0,1.0 };
int sz = sizeof(f) / sizeof(f[0]);
qsort(f, sz, sizeof(f[0]), cmp_float);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%f ", f[i]);
}
return 0;
}
4.qsort排序字符型
int cmp_char(const void* e1, const void* e2)
{
return *(char*)e1 - *(char*)e2;
}
int main()
{
char ch[] = { 'f','e','d','c','b','a' };
int sz = sizeof(ch) / sizeof(ch[0]);
qsort(ch, sz, sizeof(ch[0]), cmp_char);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%c ", ch[i]);
}
return 0;
}
5.qsort排序結構體
struct Stu
{
char name[30];
int age;
};
int cmp_Stu_name(const void* e1, const void* e2)
{
return strcmp(((struct Stu*)e1)->name,((struct Stu*)e2)->name);
}
int cmp_Stu_age(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
int main()
{
struct Stu s[] = { {"zhaoding",20},{"zhangsan",19},{"wangwu",15} };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_Stu_age);
return 0;
}
6.自定義實現my_qsort
void Swap(char* buf1, char* buf2, int width)
{
int i = 0;
for (i = 0; i < width; i++)
{
char* h = *buf1;
*buf1 = *buf2;
*buf2 = h;
buf1++;
buf2++;
}
}
void my_qsort(void* base, int sz, int width, int(*cmp)(const void* e1, const void* e2))
{
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
if (cmp((char*)base+j*width, (char*)base + (j + 1) * width) > 0)
{
Swap((char*)base + j * width, (char*)base + (j + 1) * width,width);
}
}
}
}
int main()
{
int arr[] = { 9,8,7,6,5,4,3,2,1 };
int sz = sizeof(arr) / sizeof(arr[0]);
my_qsort(arr, sz, sizeof(arr[0]), Swap);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
總結
原文鏈接:https://blog.csdn.net/buhuisuanfa/article/details/125729167
相關推薦
- 2022-06-07 FreeRTOS實時操作系統結構示例_操作系統
- 2023-07-22 SpringBoot操作MongoDB時,對同一個字段設置多次條件
- 2022-07-02 Pandas?如何處理DataFrame中的inf值_python
- 2022-05-25 <C++>詳解類對象作為類成員時調用構造和析構的時機及靜態成員解釋
- 2023-02-25 Golang嵌入資源文件實現步驟詳解_Golang
- 2022-04-05 解決IDEA .properties文件中文亂碼的問題
- 2022-04-30 python?DataFrame中loc與iloc取數據的基本方法實例_python
- 2022-03-23 shell腳本設置防止暴力破解ssh_Linux
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支