C++回調(diào)函數(shù)實(shí)現(xiàn)計(jì)算器和qsort
前言
回調(diào)函數(shù)就是一個(gè)通過函數(shù)指針調(diào)用的函數(shù)。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個(gè)函數(shù),當(dāng)這個(gè)指針被用來調(diào)用其所指向的函數(shù)時(shí),我們就說這是回調(diào)函數(shù)?;卣{(diào)函數(shù)不是由該函數(shù)的實(shí)現(xiàn)方直接調(diào)用,而是在特定的事件或條件發(fā)生時(shí)由另外的一方調(diào)用的,用于對(duì)該事件或條件進(jìn)行響應(yīng)。
今天用一個(gè)簡(jiǎn)易的計(jì)算器和qsort的實(shí)現(xiàn),帶大家深入了解回調(diào)函數(shù)
一、計(jì)算器
寫一個(gè)計(jì)算器、加法、減法、乘法、除法
1.switch語句實(shí)現(xiàn)
#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("請(qǐng)選擇:>");
scanf("%d", &input);
printf("請(qǐng)輸入兩個(gè)操作數(shù):>");
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("退出計(jì)算器\n");
break;
default:
printf("選擇錯(cuò)誤\n");
break;
}
} while (input);
return 0;
}2.回調(diào)函數(shù)實(shí)現(xiàn)
把加減乘除函數(shù),封裝成一個(gè)函數(shù)指針calc,在用戶輸入需要什么功能時(shí),只需要將函數(shù)的地址傳到回調(diào)函數(shù)中,大大的提高了代碼利用率,將功能封裝起來,高內(nèi)聚低耦合。
#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("請(qǐng)輸入2個(gè)操作數(shù):>");
scanf("%d %d", &x, &y);
ret = pf(x, y);
printf("%d\n", ret);
}
int main()
{
int input = 0;
do
{
menu();
printf("請(qǐng)選擇:>");
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("退出計(jì)算器\n");
break;
default:
printf("選擇錯(cuò)誤\n");
break;
}
} while (input);
return 0;
}二、qsort
1.冒泡排序
在學(xué)習(xí)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

相信很多小伙伴會(huì)有疑問,不是已經(jīng)學(xué)習(xí)了冒泡排序,為什么還要學(xué)習(xí)qsort,不是多此一舉嗎?但是,冒泡排序只能排整形數(shù)據(jù),那浮點(diǎn)數(shù),字符型,結(jié)構(gòu)體又該怎么實(shí)現(xiàn)呢,這就發(fā)揮出qsort的作用了。帶大家解讀一下qsort

3.qsort排序浮點(diǎn)數(shù)
#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排序結(jié)構(gòu)體
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.自定義實(shí)現(xiàn)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;
}總結(jié)
到此這篇關(guān)于C++回調(diào)函數(shù)實(shí)現(xiàn)計(jì)算器和qsort的文章就介紹到這了,更多相關(guān)C++回調(diào)函數(shù) 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Windows API實(shí)現(xiàn)遍歷所有文件并刪除的方法
這篇文章主要介紹了基于Windows API實(shí)現(xiàn)遍歷所有文件并刪除的方法,是win32應(yīng)用程序的一個(gè)比較典型的文件操作應(yīng)用技巧,需要的朋友可以參考下2015-04-04
C++標(biāo)準(zhǔn)庫中sstream與strstream的區(qū)別詳細(xì)解析
以下是對(duì)C++標(biāo)準(zhǔn)庫中sstream與strstream的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下2013-09-09
基于Qt實(shí)現(xiàn)的自定義樹結(jié)構(gòu)容器
在Qt框架中,盡管其提供了許多強(qiáng)大的容器類,但缺少一個(gè)通用的、靈活的樹結(jié)構(gòu)容器,所以本文將設(shè)計(jì)并實(shí)現(xiàn)一個(gè)可復(fù)用的自定義樹結(jié)構(gòu)容器,需要的可以參考下2024-12-12
C語言浮點(diǎn)函數(shù)中的modf和fmod詳解
這篇文章主要為大家詳細(xì)介紹了C語言浮點(diǎn)函數(shù)中的modf和fmod,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-02-02

