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

C语言——深入理解指针(4)

目录

1.回调函数

2. qsort 函数的使用

 2.1 排序整型数据

2.2 排序结构体数据

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;
}
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 = 0;
	do
	{
		printf("*************************\n");
		printf(" 1:add 2:sub \n");
		printf(" 3:mul 4:div \n");
		printf(" 0:exit \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 函数的使用

qsort是库函数,这个函数可以完成任意类型数据的排序。(使用时包含头文件<stdlib.h>)

void qsort(
    void*base,//base指向了要排序的数组的第一个元素
    size_t num,//base指向的数组中的元素个数(待排序的数组的元素的个数)
    size_t size,//base指向的数组中元素的大小(单位是字节)
    int(*compar)(const void* p1,const void*p2)//函数指针——指针指向的函数是用来比较数组中的两个元素的。
);

 2.1 排序整型数据

#include <stdio.h>
#include<stdlib.h>
//qsort函数的使⽤者得实现⼀个比较函数
int int_cmp(const void* p1, const void* p2)
{
	return (*(int*)p1 - *(int*)p2);
}
void print(int* arr,int sz)
{
	for (int i = 0; i <sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}
int main()
{
	int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr,sz , sizeof(arr[0]), int_cmp);
	//(1.数组的第一个元素,2.数组的长度,数组的第一个元素的大小,比较函数接收返回值)
	print(arr,sz);
	return 0;
}

2.2 排序结构体数据

struct str
{
	char name[20];
	int eag;
};
//怎么比较两个结构体数据?--不能直接使用><==比较
//1.可以按照名字比较
//2.可以按照年龄比较

//按照年龄比较
int cmp1(const void* p1, const void* p2)
{
	return ((struct str*)p1)->eag - ((struct str*)p2)->eag;
}
void test1()
{
	struct str arr[] = { {"zhangsan",50},{"lisi",60},{"laowang",90} };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), cmp1);
}
//按照名字比较
//注意两个字符串不能使用><==比较
//而是使用库函数strcmp来比较的
int cmp2(const void* p1, const void* p2)
{
	return strcmp(((struct str*)p1)->name, ((struct str*)p2)->name);
}
void test2()
{
	struct str arr[] = { {"zhangsan",50},{"lisi",60},{"laowang",90} };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), cmp2);
}

int main()
{
	test1();
	test2();
	printf("\n");
	return 0;
}

3. qsort 函数的模拟实现

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

int int_cmp(const void* p1, const void* p2)
{
	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;
	}
}
void bubble(void* base, int count, int size, int(*cmp)(const void*,const 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);
			}
		}
	}
}
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;
}

http://www.kler.cn/a/159502.html

相关文章:

  • 二分查找--快速地将搜索空间减半
  • ubuntu20.04 colmap 安装2024.11最新
  • 网络基础Linux
  • MySQL(5)【数据类型 —— 字符串类型】
  • 机器学习【激活函数】
  • React Hooks在现代前端开发中的应用
  • (C++20) consteval立即函数
  • MiniDumpWriteDump函数生成dmp文件
  • 【华为数据之道学习笔记】2-建立企业级数据综合治理体系
  • MySQL Shell拷贝一个库到一个新库
  • 二手物品交易系统源码小程序H5闲置物品转让APP成品
  • 前端React基础面试题
  • 【element-plus使用】el-select自定义样式、下拉框选项过长等问题解决
  • 【 Go语言使用xorm框架操作数据库】
  • 第十一届蓝桥杯青少组省赛Python中高级组真题及赏析
  • 无懈可击的身份验证:深入了解JWT的工作原理
  • SpringCloud-服务消费者Fegin调用时无法获取异常信息
  • 3090微调多模态模型Qwen-VL踩坑
  • 精通Git(第2版)读书笔记
  • Guava中的函数式编程
  • el-from表单实现lable字体大小改变
  • C++基础 -45- 类的静态数据成员
  • 深度学习之图像分类(十五)DINAT: Dilated Neighborhood Attention Transformer详解(一)
  • AOP记录操作日志
  • 【EI会议征稿中】第三届光学与机器视觉国际学术会议(ICOMV 2024)
  • 【译】 Spring AOP API