当前位置: 首页 > news >正文

怎么制作网站论坛模板陕西省高速集团建设网站

怎么制作网站论坛模板,陕西省高速集团建设网站,程显峰 wordpress,擦边球网站怎么做目录 思维导图 回调函数 案例1—计算器 案例2—qsort函数 关于qsort函数 演示qsort函数的使用 案例3—冒泡排序 整型数据冒泡排序 回调函数搞定各类型冒泡排序 cmp_int比较大小 cmp传参数 NO1. NO2. 解决方案 交换swap 总代码 今天我们学习指针难点之回调函数…目录 思维导图 回调函数 案例1—计算器 案例2—qsort函数 关于qsort函数   演示qsort函数的使用 案例3—冒泡排序  整型数据冒泡排序 回调函数搞定各类型冒泡排序 cmp_int比较大小 cmp传参数 NO1. NO2. 解决方案 交换swap 总代码 今天我们学习指针难点之回调函数。 首先我们用思维导图回顾一下前面的内容。 思维导图 回调函数 回调函数就是一个通过函数指针调用的函数。 如果你把函数的指针地址作为参数传递给另一个函数当这个指针被用来调用其所指向的函数时我们就说这是回调函数。 回调函数不是由该函数的实现方直接调用而是在特定的事件或条件发生时由另外的一方调用的用于对该事件或条件进行响应。 案例1—计算器 就前文我们学习的计算器我们再用回调函数来解决一下 #define _CRT_SECURE_NO_WARNINGS 1 //计算器 #includestdio.h void meau() {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{meau();printf(请选择);scanf(%d, input);switch (input){case 1:printf(请输入2个操作数);scanf(%d %d, x, y);ret Add(x, y);printf(ret%d\n, ret);break;case 2:printf(请输入2个操作数);scanf(%d %d, x, y);ret Sub(x, y);printf(ret%d\n, ret);break;case 3:printf(请输入2个操作数);scanf(%d %d, x, y);ret Mul(x, y);printf(ret%d\n, ret);break;case 4:printf(请输入2个操作数);scanf(%d %d, x, y);ret Div(x, y);printf(ret%d\n, ret);break;case 0:printf(退出游戏);break;default:printf(选择错误重新选择\n);break;}} while (input);return 0; } 回调函数  #define _CRT_SECURE_NO_WARNINGS 1 //计算器 #includestdio.h void meau() {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(*p)(int, int))//函数指针传参 {int x 0;int y 0;printf(请输入两个操作数\n);scanf(%d %d, x, y);int ret p(x, y);//函数调用printf(ret%d\n, ret); } int main() {int input 0;do{meau();printf(请选择\n);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(退出游戏);break;default:printf(选择错误重新选择\n);break;}} while (input);return 0; } 解释如下  在main函数中没有直接去调用函数。而是把函数指针传参给另外的一个函数calc在calc内部使用函数指针调用通过函数指针就可以找到指针指向的函数此刻被指向的函数就是回调函数。 像上图所示通过calc函数调用Add函数指针,找到Add函数就把Add函数称为回调函数。 calc称为回调函数的机制 老板组长员工 案例2—qsort函数 那出了上面回调函数的案例还有一个经典回调函数的案例qsort qsort是一个库函数底层使用的是快速排序的方式对不同数据进行排序的。 这个函数可以直接使用。 这个函数可以用来排序任意类型的数据。 对数据进行排序方法很多 冒泡排序选择排序插入排序快速排序等等。  关于qsort函数   关于qsort函数的点---qsort - C Reference (cplusplus.com) 需要包含头文件#includestdlib.h  排序整型数组两个整型可以直接使用比较排序结构体数组两个结构体的数据可能不能直接使用比较 也就是不同类型的数据比较大小的方法是有差异的 最后一个参数排序不同数据的重要点需要封装不同的函数去比较不同的数据的大小 void qsort(void* base, //指向了待排序数组第一个元素的首地址size_t num, //待排序数组的元素个数size_t size,//每个待排序数组元素的大小int (*compar)(const void* e1, const void* e2)); //函数指针compar指向了一个函数这个函数是用来比较两个元素的大小 //e1和e2存放的是两个元素的地址 //在qsort内部调用这个函数指向这个函数这个函数就被称为回调函数 // //qsort内部怎么排序我们不需要过多去探讨 //const也暂不做讲解//因为不知道要比较的元素类型所以我们使用void*指针的类型来统一存放各种类型的指针 那怎样通过元素地址去比较两个元素数据的大小呢  以int的数据为例将void*类型的数据强制转化成(int*),再作差。 当e1e2函数返回0的值 当e1e2函数返回0的值 当e1e2函数返回0 void compar_int(const void* e1, const void* e2) {return *(int*)e1 - *(int*)e2; } 那有人询问为什么不直接对元素地址const void* e1和 const void* e2解引用 作为void*指针不能直接解引用。 void* 类型的指针—不能进行解引用操作符也不能进行-整数的操作 void* 类型的指针是用来存放任意类型数据的地址 void* 无具体类型的指针 void*和int*和char*一样都是指针类型 #includestdio.h int main() {char a x;char* pa a;int b 1;void* p b;//存放int*p a;//存放char*return 0; } 演示qsort函数的使用 #includestdio.h #includestdlib.h void print(int arr[], int sz) {int i 0;for (i 0; i 10; i){printf(%d , arr[i]);} }void qsort(void* base, size_t num,size_t size,int (*compar)(const void*, const void*));void compar_int(const void* e1, const void* e2) {return *(int*)e1 - *(int*)e2; } void test1() {int arr[] { 10,9,8,7,6,5,4,3,2,1 };int sz sizeof(arr) / sizeof(arr[0]);print(arr, sz);printf(\n);qsort(arr, sz, sizeof(arr[0]), compar_int);print(arr, sz); }int main() {test1();test2();return 0; }以上我只是以整型为例结构体数据数组也是一样的逻辑大家可以自行分析。 下面结构体 #includestdio.h #includestdlib.h #includestring.h//void qsort(void* base,size_t num,size_t size,int (*compar)(const void*, const void*));struct Stu {char name[20];int age; }; //结构体数据怎么比较呢 //按照年龄比较 //按照名字比较//按照年龄 void compar_stu_by_age(const void* e1, const void* e2) {return ((struct Stu*)e1)-age - ((struct Stu*)e2)-age;//return (*(struct Stu*)e1).age - (*(struct Stu*)e2).age; } void test2() {struct Stu arr[] { {zhangsan,20},{lisi,30},{wangwu,12} };int sz sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), compar_stu_by_age);} //按照名字 void compar_stu_by_name(const void* e1, const void* e2) {return ((struct Stu*)e1)-name - ((struct Stu*)e2)-name;//return (*(struct Stu*)e1).name - (*(struct Stu*)e2).name; } void test2() {struct Stu arr[] { {zhangsan,20},{lisi,30},{wangwu,12} };int sz sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), compar_stu_by_name);}int main() {test2();return 0; }只要qsort函数使用得当可以对任何数据进行排序  案例3—冒泡排序  使用回调函数模拟实现qsort(采用冒泡的方式 整型数据冒泡排序 (这种方式只能排列整数存在局限性 //冒泡排序 #includestdio.h void bubble_sort(int arr[], int sz) {int i 0;for (i 0; i sz - 1; i){int j 0;for (j 0; j sz - 1 - i; j){if (arr[j] arr[j 1]){int tmp 0;tmp arr[j];arr[j] arr[j 1];arr[j 1] tmp;}}} } void print_arr(int arr[], int sz) {int i 0;for (i 0; i sz; i){printf(%d , arr[i]);} } int main() {int arr[10] { 9,8,7,6,5,4,3,2,1,0 };int sz sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz);print_arr(arr, sz); } 回调函数搞定各类型冒泡排序 经过分析冒泡排序我们得到 void bubble_sort(void* base, size_t num, size_t size,                             int (*cmp)(const void* e1, const void* e2)) cmp_int比较大小 以整型为例  int (*cmp)(const void* e1, const void* e2) e1是一个指针存放了一个要比较的元素的地址。 e2是一个指针存放了一个要比较的元素的地址。 e1指向的元素e2指向的元素返回0的数字。 e1指向的元素e2指向的元素返回0的数字。 e1指向的元素e2指向的元素返回0的数字。 cmp是函数指针指向一个我们程序想要待排序的数组。 将比较函数cmp_int的地址传给cmp即可。 //比较大小 void cmp_int(const void* e1, const void* e2) {return *(int*)e1 - *(int*)e2; } //这里就是将cmp_int的地址在调用函数bubble_sort时将其传过去即可。 cmp传参数 NO1. 有同学提出直接对待排序的数组首元素地址解引用找到e1的地址然后通过一个元素的大小或者1可以找到e2的地址可以吗当然不可以 作为void*指针不能直接解引用。 void* 类型的指针—不能进行解引用操作符也不能进行-整数的操作 void* 类型的指针是用来存放任意类型数据的地址 void* 无具体类型的指针 void*和int*和char*一样都是指针类型 NO2. 有同学又提出那将void*的指针强制转换成我们想要的int*或double*等再1可以吗           不可以理由就是强制转换存在在于我们公共的bubble_sort排序函数中时不能随着待排序的数组数据类型不同而改变我们只能改变不同数据类型的不同比较方法。 解决方案 //if(arr[j]arr[j1])if (cmp( (char*)basej*size,(char*)base(j1)*size )0){int tmp 0;tmp arr[j];arr[j] arr[j 1];arr[j 1] tmp;} 交换swap 当我们只知道元素的起始地址并不知道元素的类型所以我们并没有合适的中间值类型tmp创建。所以我们换一种方法。 我们已知元素e1和e2的起始地址和每个元素的大小。 那我们可以用一个一个char类型的数据交换用for循环 直到每个元素的大小size结束也就是元素交换完成。 //交换数据 void change(char* buf1, char* buf2,size_t size) {char i 0;for (i 0; i size; i){char tmp 0;tmp *buf1;*buf1*buf2;*buf2 tmp;buf1;//*buf1buf2;//*buf2} } 总代码 //冒泡排序 #includestdio.h void print_arr(int arr[], int sz) {int i 0;for (i 0; i sz; i){printf(%d , arr[i]);} }void bubble_sort(void* base, size_t num, size_t size,int (*cmp)(const void* e1, const void* e2)) {int i 0;for (i 0; i num - 1; i){int j 0;for (j 0; j num - 1 - i; j){//if(arr[j]arr[j1])if (cmp( (char*)basej*size,(char*)base(j1)*size )0){change((char*)base j * size, (char*)base (j 1) * size, size);}}} } //交换数据 void change(char* buf1, char* buf2,size_t size) {char i 0;for (i 0; i size; i){char tmp 0;tmp *buf1;*buf1*buf2;*buf2 tmp;buf1;//*e1buf2;//*e2} } //比较大小 void cmp_int(const void* e1, const void* e2) {return *(int*)e1 - *(int*)e2;//0 }void test1() {int arr[10] { 9,8,7,6,5,4,3,2,1,0 };int sz sizeof(arr) / sizeof(arr[0]);print_arr(arr, sz);printf(\n);bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);print_arr(arr, sz); }int main() {test1(); } 当然我们也可以用结构体类型去测试一下 试试 ✔✔✔✔✔最后感谢大家的阅读若有错误和不足欢迎指正旗鼓相当 代码------→【gitee:唐棣棣 (TSQXG) - Gitee.com】 联系------→【邮箱2784139418qq.com】
http://www.w-s-a.com/news/665777/

相关文章:

  • html网站简易模板国内买机票的网站建设
  • 百度关键词分析工具百度seo排名软
  • 自己怎样做免费网站ueditor 上传wordpress
  • 深圳高端网站开发网站建设公司销售技巧
  • 网站建设的优势是什么意思可拖动网站
  • 建设什么企业网站网站微信认证
  • 网站开发的平台成都有哪些好玩的
  • 上海金瑞建设集团网站怎么创建免费网页
  • 柳州做网站设计的公司制作网站软件下载
  • 湖南seo网站开发苏州网络营销及网站推广
  • 如何发布自己做的网站郑州网站建设定制开发
  • 重庆网站商城宁波网络公司联系方式
  • 个人网站建设实验心得seo课程简介
  • 免费自助建站系统下载推广app网站
  • 用scala做的网站标题关键词优化技巧
  • 百度网站评级wordpress忘记admin
  • 建筑标准下载网站263企业邮箱 登陆
  • 旅游房地产网站建设德保网站建设
  • 网站高端建设wordpress订单系统
  • 建设网站成本增加网站备案
  • 行业网站建设方案百度云图片转wordpress
  • 如何建设网站推广平台营销客户管理软件
  • 网站制作南宁如何撰写一个网站规划建设方案
  • 建站网站和维护需要会什么杭州人防质监站网址
  • 唐山免费做网站莱芜吧贴吧最新消息
  • 韶关市建设工程造价网站网络营销的平台有哪些
  • 网站建设费大概多少钱成都网站建设低价
  • 做表格的网站东莞常平房价
  • 国家级建设网站高密做网站哪家强价位
  • 江西省新的建设厅三类人员网站做标记网站