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

河南网站建设价位广州seo排名收费

河南网站建设价位,广州seo排名收费,嘉定企业网站建设,虚拟机中做网站前言 在C语言的学习中,指针一直是一个让人又爱又恨的话题。它强大而灵活,但也容易让人陷入困惑。今天,我们就来深入探讨指针的一个重要应用——回调函数,以及基于回调函数的经典函数qsort。 一、回调函数:隐藏在背后…

前言

在C语言的学习中,指针一直是一个让人又爱又恨的话题。它强大而灵活,但也容易让人陷入困惑。今天,我们就来深入探讨指针的一个重要应用——回调函数,以及基于回调函数的经典函数qsort。

一、回调函数:隐藏在背后的英雄

先来看一个实际问题。在编写代码时,我们常常会遇到一些重复的逻辑,比如在实现一个简单的计算器程序时,输入输出的操作是重复的,只有具体的计算逻辑不同。传统的解决方法是写多个函数,每个函数都包含输入输出和计算逻辑,但这样会导致代码冗余。而回调函数的出现,就是为了解决这个问题。

1.1 回调函数是什么

回调函数本质上就是一个通过函数指针调用的函数。当你把一个函数的指针(地址)作为参数传递给另一个函数时,这个指针被用来调用其所指向的函数,那么被调用的函数就被称为回调函数。它的调用不是由函数的实现方直接调用,而是在特定的事件或条件发生时由另一方调用,用于对该事件或条件进行响应。

1.2 使用回调函数改造计算器程序

一个使用回调函数改造计算器程序的例子。改造前的代码中,每个计算操作(加、减、乘、除)都需要单独写输入输出和计算逻辑,代码冗长且重复。而使用回调函数后,我们把计算逻辑的函数地址作为参数传递给一个通用的计算函数calc,这样就避免了重复代码的编写。

void calc(int(*pf)(int, int))//函数calc调用函数指针来访问对应的函数
{int ret = 0;int x, y;printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = pf(x, y);printf("ret = %d\n", ret);
}

在main函数中,我们只需要根据用户的选择调用calc函数,并将对应的计算函数(如add、sub、mul、div)的地址传递给它即可。

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;
}

这种使用回调函数的方式,不仅让代码更加简洁,而且提高了代码的可维护性和可扩展性。当我们需要添加新的计算操作时,只需要定义一个新的计算函数,并在main函数中添加对应的分支即可,而不需要修改calc函数。
完整代码:

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 ret = 0;int x = 0;int y = 0;printf("请输入操作数:");scanf("%d %d", &x, &y);ret = pf(x, y);printf("ret = %d\n", ret);
}
int main()
{int x = 0;int y = 0;int input = 1;int ret = 0;int(*p[5])(int x, int y) = { 0,add,sub,mul,div };do{printf("*********************\n");printf("1、 add        2、sub \n");printf("3、 mul        4、div \n");printf("0、 eixt              \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;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、qsort函数:排序界的瑞士军刀

qsort函数是C语言标准库中的一个非常强大的排序函数,它使用了快速排序算法,可以对任意类型的数据进行排序。它的强大之处在于,它允许用户自定义比较函数,通过回调函数的方式,来决定数据的排序规则。

2.1 使用qsort函数排序整型数据

首先,我们需要定义一个比较函数int_cmp,这个函数接收两个const void类型的参数,分别指向要比较的两个元素。在比较函数中,我们**需要将这两个参数强制转换为int类型,然后比较它们所指向的整数值**。

int int_cmp(const void * p1, const void * p2)
{return (*(int *)p1 - *(int *)p2);
}

然后,在main函数中,我们调用qsort函数,并将数组、数组的大小、每个元素的大小以及比较函数作为参数传递给它。

int main()
{int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };int i = 0;qsort(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;
}

运行程序后,我们可以看到数组被成功排序。
完整代码:

int int_cmp(const void* p1, const void* p2)
{return (*(int*)p1 - *(int*)p2);//转换为int* 类型再进行解引用操作
}
int main()
{int arr[] = { 1,3,5,7,9,2,4,6,8,10 };int i = 0;qsort(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;
}

在这里插入图片描述

2.2 使用qsort函数排序结构体数组

qsort函数不仅可以对基本数据类型进行排序,还可以对结构体数组进行排序。我们定义一个Stu结构体,包含学生的姓名和年龄。然后,我们定义了两个比较函数cmp_stu_by_age和cmp_stu_by_name,分别按照年龄和姓名对学生进行排序。

int cmp_stu_by_age(const void* e1, const void* e2)
{return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}int cmp_stu_by_name(const void* e1, const void* e2)
{return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}

在test2和test3函数中,我们分别调用qsort函数,并将结构体数组、数组的大小、每个元素的大小以及对应的比较函数作为参数传递给它。

void test2()
{struct Stu s[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15} };int sz = sizeof(s) / sizeof(s[0]);qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
}void test3()
{struct Stu s[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15} };int sz = sizeof(s) / sizeof(s[0]);qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}

通过这种方式,我们可以非常灵活地对结构体数组进行排序,而不需要自己编写复杂的排序算法。

三、模拟实现qsort函数:深入理解回调函数与void*

在课件的最后,我们看到了一个模拟实现qsort函数的例子。这个例子不仅让我们更加深入地理解了qsort函数的工作原理,还让我们学习了如何使用回调函数和void*指针。

3.1 void*指针的作用

在C语言中,void指针是一种特殊的指针,它可以指向任意类型的数据。当我们不确定要操作的数据类型时,可以使用void指针。在模拟实现qsort函数时,我们使用void*指针来指向数组的首地址,这样就可以对任意类型的数据进行操作。

3.2 模拟实现qsort函数

在模拟实现qsort函数时,我们使用了冒泡排序算法。首先,我们定义了一个比较函数int_cmp,这个函数与前面的例子中的比较函数相同。然后,我们定义了一个_swap函数,用于交换两个元素的值。在_swap函数中,我们使用了void指针来指向要交换的两个元素,并通过强制类型转换将它们转换为char指针,然后逐字节地交换它们的值。

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;}
}

接下来,我们定义了bubble函数,这个函数实现了冒泡排序算法。在bubble函数中,我们使用了void指针来指向数组的首地址,并通过强制类型转换将它转换为char指针,然后逐个比较数组中的元素,并根据比较函数的结果交换它们的值。

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);}}}
}

最后,在main函数中,我们调用bubble函数,并将整型数组、数组的大小、每个元素的大小以及比较函数作为参数传递给它。

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;
}

通过模拟实现qsort函数,我们不仅加深了对回调函数和void*指针的理解,还学习了如何使用这些知识来解决实际问题。

四、总结

今天,我们深入探讨了指针的一个重要应用——回调函数,以及基于回调函数的经典函数qsort。我们看到了回调函数如何帮助我们简化代码,提高代码的可维护性和可扩展性。我们也看到了qsort函数的强大功能,它可以对任意类型的数据进行排序,并且允许用户自定义排序规则。最后,我们通过模拟实现qsort函数,深入理解了回调函数和void*指针的作用。

希望这篇文章能帮助你更好地理解指针和回调函数,让你在C语言的学习之路上更进一步。如果你对这篇文章感兴趣,欢迎点赞、收藏和评论,你的支持是我继续创作的动力。

http://www.dtcms.com/wzjs/429673.html

相关文章:

  • 网站关键词搜索排名广告营销策略有哪些
  • 长沙教育网站开发软文营销文章范文
  • web前端面试以前都是做的小网站查排名
  • 亚马逊云服务器收费标准搜索引擎优化的概念
  • 制作网页一般需要兼容哪些网站电子商务主要学什么
  • 网站制作加谷歌推广手机系统流畅神器
  • 湛江企业网站seo重庆放心seo整站优化
  • 网站建设原则应考虑哪些方面友情链接推广平台
  • 章丘网站建设中国市场营销网
  • wordpress内部结构国内好的seo
  • 怎么做网站的浏览量seo职位
  • 建网站销售常见问题长春关键词优化报价
  • 那些网站是专门做一些调研的最好的bt磁力搜索引擎
  • 上虞网站建设公司合肥网站优化技术
  • 制作企业网站的报告智推教育seo课程
  • 网站开发可以学吗哈尔滨关键词排名工具
  • 郑州做网站软件玄幻小说百度风云榜
  • 苏州手机网站制作阿里巴巴官网首页
  • 西峡微网站建设独立站seo搜索优化
  • 网站怎么做好达内教育
  • 自己做捕鱼网站能不能挣钱巨量算数数据分析入口
  • 厦门市app开发网站建设公司泉州网站建设优化
  • 网站配色 要用什么原则绍兴百度seo
  • 什么网站可以做外贸免费网站生成器
  • 个人开网站深圳推广公司排行榜
  • 如何判断网站是用织梦做的济源网络推广
  • 高台网站建设浏览器直接进入网站的注意事项
  • 展馆设计论文公司关键词排名优化
  • 云南网站建设营销国内最好用的免费建站平台
  • 2022国内外重大新闻事件10条北京网站seo费用