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

厦门网站建设阳哥建网站需要软件

厦门网站建设阳哥,建网站需要软件,企业解决方案公司排名,wordpress登录和没登录菜单文章目录 深入理解指针(五)1.回调函数是什么?2.qsort使用举例2.1 使用qsort函数排序整型数据强调 2.2 使用qsort排序结构数据 3.qsort函数的模拟实现 深入理解指针(五) 1.回调函数是什么? 回调函数就是⼀个通过函数指针调⽤的函数。 如果你把函数的指…

文章目录

  • 深入理解指针(五)
    • 1.回调函数是什么?
    • 2.qsort使用举例
      • 2.1 使用qsort函数排序整型数据
        • 强调
      • 2.2 使用qsort排序结构数据
    • 3.qsort函数的模拟实现

深入理解指针(五)

1.回调函数是什么?

回调函数就是⼀个通过函数指针调⽤的函数

如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数时,被调用的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条 件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进⾏响应。

深入理解指针(四)**(可以移步主页)**中我们写的计算机的实现的代码中,红⾊框中的代码是重复出现的,其中虽然执⾏计算的逻辑 是区别的,但是输⼊输出操作是冗余的,有没有办法,简化⼀些呢?

可以将相似代码抽象成函数

因为红⾊框中的代码,只有调⽤函数的逻辑是有差异的,我们可以把调⽤的函数的地址以参数的形式 传递过去,使⽤函数指针接收,函数指针指向什么函数就调⽤什么函数,这⾥其实使⽤的就是回调函 数的功能。

有了函数指针后,函数的调用可以使用函数名调用,也可以使用函数指针来调用

//使⽤回调函数改造前 
#include <stdio.h>
int add(int a, int b)
{return a + b;
}
int sub(int a, int b)
{return a - b;
}
int mul(int a, int b)
{return a * b;
}
int div(int a, int b)
{return a / b;
}
int main()
{int x, y;int input = 1;int ret = 0;do{printf("*************************\n");printf(" 1:add 2:sub \n");printf(" 3:mul 4:div \n");printf("*************************\n");printf("请选择:");scanf("%d", &input);switch (input){case 1:printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = add(x, y);printf("ret = %d\n", ret);break;case 2:printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = sub(x, y);printf("ret = %d\n", ret);break;case 3:printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = mul(x, y);printf("ret = %d\n", ret);break;case 4:printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = div(x, y);printf("ret = %d\n", ret);break;case 0:printf("退出程序\n");break;default:printf("选择错误\n");break;}} while (input);return 0;
}
//使⽤回调函数改造后 
#include <stdio.h>
int add(int a, int b)
{return a + b;
}
int sub(int a, int b)
{return a - b;
}
int mul(int a, int b)
{return a * b;
}
int div(int a, int b)
{return a / b;
}
void calc(int(*pf)(int, int))
{int ret = 0;int x, y;printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = pf(x, y);printf("ret = %d\n", ret);
}
int main()
{int input = 1;do{printf("*************************\n");printf(" 1:add 2:sub \n");printf(" 3:mul 4:div \n");printf("*************************\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;
}

2.qsort使用举例

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

qsort是库函数,可以排序任意类型的数据,底层使用的是快速排序的方式(头文件为(<stdlib.h>)

在这里插入图片描述

下边对qsort个参数进行解释

void qsort(void* base,//指针,指向的是待排序的数组的第一个元素size_t num,//base指向的待排序数组的元素的个数size_t size,//base指向待排序数组元素的大小int(*compar)(const void*, const void*)//函数指针
);

qosrt 函数有实现者

qosrt 函数的使用者 —-明确的知道要排序的是什么数据,这些数据应该如何比较,所以提供两个元素的比较函数

深入理解指针(三)**(可以移步主页查看详情)**中,我们提到了冒泡排序,代码如下

#include<stdio.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 = arr[j + 1];arr[j + 1] = arr[j];arr[j] = 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[] = { 9,8,7,6,5,4,3,2,1 };//排为升序int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz);print_arr(arr, sz);
}

很容易发现,该代码只适用于整数

那么在使用冒泡排序的情况下,要改造函数让它能够排序任意类型的数据,该如何做到

问题的主要原因是

两个整型元素可以直接用>比较,但是两个字符串、两个结构体是不能用>比较的

参数以及数据的交换也需要更改

我们可以把两个元素的比较封装成函数,然后把函数地址传给排序函数

#include <stdio.h>
//qosrt函数的使⽤者得实现⼀个⽐较函数 
int int_cmp(const void* p1, const void* p2)
{//强制类型转换if(*(int *)p1>*(int *)p2)//此处不能写成if(*p1>*p2) 因为void*类型的指针是无具体类型的指针,这种类型的指针不能直接解引用,也不能+-整数运算return 1;else if(*(int *)p1==*(int *)p2)return 0;elsereturn -1;
}
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;
}
强调

void*类型的指针是无具体类型的指针,这种类型的指针不能直接解引用,也不能±整数运算

最后我们对代码做一下简化

int int_cmp(const void* p1, const void* p2)
{return (*(int*)p1 - *(int*)p2);
}
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;
}

2.2 使用qsort排序结构数据

这⾥需要补充介绍结构指针和结构体成员访问操作符 ->;

结构体变量.成员名
结构体指针.成员名

结构体补充:

struct Stu//学生
{char mane[20];//名字int age;//年龄
};
int main()
{struct Stu s={"zhangsan",18};printf("%s %d",s.name,s.age);return 0;
}
void print(struct Stu* ps)
{//printf("%s %d",(*ps).name,(*ps).age); //可以,但是啰嗦printf("%s %d",ps->name,ps->age);//这两者等价
}
struct Stu//学生
{char mane[20];//名字int age;//年龄
};
int main()
{struct Stu s={"zhangsan",18};print(&s);return 0;   
}

这两个结构体怎么比

1.按照名字比较————-字符串比较—–strcmp(头文件为<string.h>)

2.按照年龄比较————-整型比较

那strcmp函数是怎么比较字符串大小的呢

按照对应字符串中字符的ASII码值比较

在这里插入图片描述

上图中,两个字符串前两个相同,然后比较第三个字符的ASII码值

所以上边的字符串大

struct Stu //学⽣
{char name[20];//名字 int age;//年龄 
};
//假设按照年龄来⽐较 
int cmp_stu_by_age(const void* e1, const void* e2)
{return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;//跟之前一样,这里同样需要强制类型转换
}
//strcmp - 是库函数,是专⻔⽤来⽐较两个字符串的⼤⼩的 
//假设按照名字来⽐较 
int cmp_stu_by_name(const void* e1, const void* e2)
{return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
//按照年龄来排序 
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);
}
int main()
{test2();test3();return 0;
}

3.qsort函数的模拟实现

使⽤回调函数,模拟实现qsort(采⽤冒泡的⽅式)。

注意:这⾥第⼀次使⽤ void* 的指针,讲解 void* 的作⽤。

#include <stdio.h>
int int_cmp(const void* p1, const void* p2)//void接收任意类型指针
{return (*(int*)p1 - *(int*)p2);
}
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;char tmp=p1;//两种写法等价*p1=*p2;*p2=tmp;p1++;p2++;   }
}
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)//size是宽度 *size可以跳过1个数据{_swap((char*)base + j * size, (char*)base + (j + 1) * size, size);}}}
}
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;
}

上述代码中

base相当于arr[0]

在swap函数中

强制转换成char*类型的目的是:把一大块数据切成小块交换 一个字节一个字节的交换

欢迎大家三连🎉 🎉 🎉


文章转载自:

http://aVujsHL9.zcfsq.cn
http://wubjxZYG.zcfsq.cn
http://buwZZiDA.zcfsq.cn
http://bA9zpPmB.zcfsq.cn
http://LcNeWtAN.zcfsq.cn
http://gs3WPocM.zcfsq.cn
http://4n0DRd6r.zcfsq.cn
http://CqsY6PEh.zcfsq.cn
http://hdWyei4C.zcfsq.cn
http://NzsAFfqp.zcfsq.cn
http://PPrp9uGe.zcfsq.cn
http://7kXbggwC.zcfsq.cn
http://wkNQgYxc.zcfsq.cn
http://TRSg87Ps.zcfsq.cn
http://tO8RXuPi.zcfsq.cn
http://4R2NWZZy.zcfsq.cn
http://OHqm8eki.zcfsq.cn
http://eBXMDwuU.zcfsq.cn
http://65DKqh2Z.zcfsq.cn
http://FsWfHvtb.zcfsq.cn
http://rcIT3PY7.zcfsq.cn
http://kiwMCgKK.zcfsq.cn
http://ph5NNPez.zcfsq.cn
http://qUN95akK.zcfsq.cn
http://HgEDNbQV.zcfsq.cn
http://wjoY01DP.zcfsq.cn
http://LSCt4vBO.zcfsq.cn
http://C5e2ZzNP.zcfsq.cn
http://ilb18LSA.zcfsq.cn
http://tnNKsf1W.zcfsq.cn
http://www.dtcms.com/wzjs/619695.html

相关文章:

  • 崇文手机网站建设企业网站ui设计
  • 基于cms设计网站的背景意义保定投递网站建设
  • 网站设计咨询电话广东新闻联播林红
  • 网站后台编辑器不显示火车头wordpress自动排版
  • 商城网站主机装修贷
  • 昆明网站制作前十企业网站模板 优帮云
  • 学习网站开发技术百度词条优化工作
  • 买的网站模板会影响深圳做app网站建设
  • 网站首页权重国内网站建设代理
  • 扬州大发网站建设wordpress附件修复
  • 广西南宁电商网站建设抖音代运营服务协议
  • 专业网页设计和网站制作公司中信建设有限责任公司临空经济区
  • 个体工商户经营范围网站开发wordpress首页模块修改
  • 做网站一个月多少钱专业做农牧应聘的网站
  • 旅游网站系统设计wordpress模板top破解版
  • 制作手机网站什么软件焦作企业网站建设
  • 手机网站制作软件下载宝塔网站301重定向怎么做
  • 两人做性视频网站手机棋牌app软件开发
  • 网站关键词几个建设通网站是什么网站
  • 简述网站建设流程网站开发一个模板费用
  • 做网站一班需要多少钱wordpress文章只显示题目
  • 官网网站源码模板网站的缺点
  • 专业的网站建设公网站如何收费
  • 晋城市 制作网站企业门户网站建设市场
  • 工具站seoartisteer 做的网站
  • 计算机机应用网站建设与维护浅谈阿里企业的电子网站建设
  • 移动网站建设推荐网站开发宣传广告
  • 新手学网页设计的网站wordpress 纯净版下载地址
  • 网站建设的项目计划阿克苏网站建设服务
  • 网站群建设管理办法网站建设实施流程