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

河南网站建设价位攀枝花网站seo

河南网站建设价位,攀枝花网站seo,在局网站 作风建设,wordpress图片灯箱效果修改前言 在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/353624.html

相关文章:

  • 一个网站一个月发多少外链比较合适厦门关键词排名推广
  • 做外贸在那些网站找业务史上最强大的搜索神器
  • 房产网签合同嘉峪关seo
  • app手机端电子商务网站功能关键词排名网络推广
  • 做网站猫要做端口映射吗真正免费建站
  • 自己做游戏资讯网站如何快速推广一个app
  • 专注宜昌网站建设建站工具
  • 大连网站建设多少钱html网页设计模板
  • wordpress自动插件下载百度关键词在线优化
  • 成都科技网站建设找哪家网站关键词优化外包
  • 北京上海网站建设公司火爆产品的推广文案
  • 手机网站模板软文营销广告案例
  • 做网站的顶部图片百度快照是干嘛的
  • 淘客做网站怎么备案广东seo推广公司
  • 延吉市建设局网站搜索引擎营销的手段包括
  • 网站建设工作都干啥郑州做网站公司排名
  • 如何创建属于自己的网页福州百度快照优化
  • 网站推广排名报价打开网站搜索
  • wordpress企业建站教程石家庄整站优化技术
  • 太阳代理ip官网免费seo软件
  • 网站建设经费预算鹤壁搜索引擎优化
  • 建设类招标代理公司网站人工在线客服
  • 购买网站空间送域名广州企业网站建设
  • 特色专业建设展示网站 湖北网站出售
  • 建立购物网站seo推广教程视频
  • 网站建设正版软件查询网站流量
  • 南阳市建网站公河南seo
  • 播州区住房和城乡建设局网站新闻头条今日新闻下载
  • 做网站的总要求上门免费网络推广软件有哪些
  • 新疆建设兵团国资委网站百度广告联盟点击一次多少钱