指针进阶复习, 回调函数使用实例

指针进阶复习

int Add(int x, int y)
{
    
    
	return x + y;
}
int main()
{
    
    
	//指针数组
    int* arr[10];
	//数组指针 
	int* (*pa)[10] = &arr;
*pa pa前面加一颗星说明pa是指针 指向的是[10]说明指向数组有10个元素
pa指向数组arr的每个元素类型是int* 所以前面加上int*
	函数指针
	int(*paAdd)(int,int) =  Add; //函数名就是函数的地址&Add也是可以
	//int sum = (*paAdd)(1, 2);//调用Add函数
	int sum = paAdd(1,2);    //这样调用也是可以的
	printf("%d\n", sum);
	函数指针的数组
	/*int(*paAdd[4])(int, int);*/
	指向函数指针数组的指针
	/*int(*(*paaAdd)[4])(int, int) =&paAdd;*/
paaAdd先和*结合是指针,指向的是数组,有四个元素,
每个元素类型是int(*)(int,int)函数指针
	return 0;
}

利用回调函数模拟冒泡排序

这是冒泡排序的具体代码

void Bubble_sort(int arr[], int sz)
{
    
    
	int i = 0;
	for (i = 0; i < sz - 1; i++)//趟数  这里一共要有sz-1躺就可以完成所有数字
	{
    
    
		//每一趟的冒泡排序
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
    
    
			if (arr[j] > arr[j + 1])
			{
    
    
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
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);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
    
    
		printf("%d ", arr[i]);
	}
	return 0;
}

qsort库函数qsort的参数

void qsort(void* base, 
		  size_t num, 
		  size_t width, 
		  int( *cmp)(const void *e1, const void *e2));
		  //cmp是比较函数

	比较函数的特点
	当e1 < e2的时候   会返回小于0的数字
	当e1 = e2的时候   会返回一个0
	当e1 > e2的时候   会返回一个大于0的数字

下面是如何使用qsort库函数的

排序整型的方法

int cmp_int(const void* e1, const void* e2) 
//这里的e1和e2就是接收你要比较的两个元素的地址
{
    
    
	//比较两个整型值的
	return *(int*)e1 - *(int*)e2;
}
void test1()
{
    
    
	//这是计算整型的 快速排序的方法
	int arr[10] = {
    
     9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), cmp_int); //sizeof(arr[0])每一个元素所占的字节
	int i = 0;
	for (i = 0; i < sz; i++)
	{
    
    
		printf("%d ", arr[i]);
	}
}

排序float型的方法

int cmp_float(const void* e1, const void* e2)
{
    
    
	//比较两个float类型的
	return ((int)(*(float*)e1 - *(float*)e2));
}
void test2()
{
    
    
	//这是计算float型  快速排序的方法
	float f[] = {
    
     9.0, 8.0, 7.0, 6.0, 5.0, 4.0 };
	int sz = sizeof(f) / sizeof(f[0]);
	qsort(f, sz, sizeof(f[0]), cmp_float);
	int j = 0;
	for (j = 0; j < sz; j++)
	{
    
    
		printf("%f ", f[j]);
	}
}

排序结构体类型按照年龄进行排序

int cmp_stu_by_age(const void* e1, const void* e2)
{
    
    
	return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
void test3()
{
    
    
	struct Stu s[3] = {
    
     {
    
     "zhangsan", 20 }, {
    
     "lisi", 30 }, {
    
     "wangwu", 10 } };
	int sz = sizeof(s) / sizeof(s[0]);
	qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
	
}

排序结构体类型按姓名 -字符串进行排序

int cmp_stu_by_name(const void* e1, const void* e2)
{
    
    
	//比较姓名就是比较字符串
	//比较字符串不能直接用><=来比较,应该用strcmp函数
	 return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
	 //strcmp 也是第一个大于第二个返回一个大于0的数字
	 //strcmp 第一个等于第二个返回0的数字
	 //strcmp 第一个小于第二个 返回小于0的数字
}
void test4()
{
    
    
	struct Stu s[3] = {
    
     {
    
     "zhangsan", 20 }, {
    
     "lisi", 30 }, {
    
     "wangwu", 10 } };
	int sz = sizeof(s) / sizeof(s[0]);
	qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
	//第一个参数:待排序数组的元素地址 也就是目标数组的起始位置
	//第二个参数:待排序数组的元素个数
	//第三个参数:待排序数组的每个元素的大小-单位是字节 width宽度,元素大小就是一个元素有几个字节
	//第四个参数:是函数指针,比较两个元素的所用函数地址-这个函数使用者自己实现
	//			  函数指针的两个参数是:待比较的两个元素的地址

}

下面是所有排序代码,放在一起

int cmp_int(const void* e1, const void* e2) 
//这里的e1和e2就是接收你要比较的两个元素的地址
{
    
    
	//比较两个整型值的
	return *(int*)e1 - *(int*)e2;
}
void test1()
{
    
    
	//这是计算整型的 快速排序的方法
	int arr[10] = {
    
     9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), cmp_int); //sizeof(arr[0])每一个元素所占的字节
	int i = 0;
	for (i = 0; i < sz; i++)
	{
    
    
		printf("%d ", arr[i]);
	}
}
int cmp_float(const void* e1, const void* e2)
{
    
    
	//比较两个float类型的
	return ((int)(*(float*)e1 - *(float*)e2));
}
void test2()
{
    
    
	//这是计算float型  快速排序的方法
	float f[] = {
    
     9.0, 8.0, 7.0, 6.0, 5.0, 4.0 };
	int sz = sizeof(f) / sizeof(f[0]);
	qsort(f, sz, sizeof(f[0]), cmp_float);
	int j = 0;
	for (j = 0; j < sz; j++)
	{
    
    
		printf("%f ", f[j]);
	}
}
int cmp_stu_by_age(const void* e1, const void* e2)
{
    
    
	return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
void test3()
{
    
    
	struct Stu s[3] = {
    
     {
    
     "zhangsan", 20 }, {
    
     "lisi", 30 }, {
    
     "wangwu", 10 } };
	int sz = sizeof(s) / sizeof(s[0]);
	qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
	
}
int cmp_stu_by_name(const void* e1, const void* e2)
{
    
    
	//比较姓名就是比较字符串
	//比较字符串不能直接用><=来比较,应该用strcmp函数
	 return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
	 //strcmp 也是第一个大于第二个返回一个大于0的数字
	 //strcmp 第一个等于第二个返回0的数字
	 //strcmp 第一个小于第二个 返回小于0的数字
}
void test4()
{
    
    
	struct Stu s[3] = {
    
     {
    
     "zhangsan", 20 }, {
    
     "lisi", 30 }, {
    
     "wangwu", 10 } };
	int sz = sizeof(s) / sizeof(s[0]);
	qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
	//第一个参数:待排序数组的元素地址 也就是目标数组的起始位置
	//第二个参数:待排序数组的元素个数
	//第三个参数:待排序数组的每个元素的大小-单位是字节 width宽度,元素大小就是一个元素有几个字节
	//第四个参数:是函数指针,比较两个元素的所用函数地址-这个函数使用者自己实现
	//			  函数指针的两个参数是:待比较的两个元素的地址

}

下面使用回调函数实现冒泡排序可以排其他类型顺序

//这是交换代码
void Swap(char* buf1, char* buf2, int width)
{
    
    
	int i = 0;
	for (i = 0; i < width; i++)
	{
    
    
		char tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++;
		buf2++;
	}
}
//实现bubble_sort函数的程序员,他是否知道未来排序的数据类型 - 不知道
//那程序员也不知道,待比较的两个元素的类型
void bubble_sort(void* base,int sz,  int width, int(*cmp)(void* e1,void* e2))//base目标数组起始位置 width是一个元素有几个字节
{
    
    
	int i = 0;
	//趟数
	for (i = 0; i < sz - 1; i++)
	{
    
    
		//每一趟比较的对数
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
    
    
			//两个元素的比较
			if (cmp((char*)base+j*width,(char*)base+(j+1)*width)>0)
			{
    
    
				//交换
				Swap((char*)base + j*width, (char*)base + (j + 1)*width, width);
			}
		}
	}
}
void test5()
{
    
    
	int arr[10] = {
    
     9, 8, 7, 6, 5, 4, 3, 2, 1 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	/*
	使用bubble_sort的程序员一定知道自己排序的是什么数据
	就应该知道如何比较待排序数组中的元素
	*/
	bubble_sort(arr,sz,sizeof(arr[0]),cmp_int);
}
void test6()
{
    
    
	struct Stu s[3] = {
    
     {
    
    "zhangsan",20}, {
    
    "lisi",30}, {
    
    "wangwu",10} };
	int sz = sizeof(s) / sizeof(s[0]);
	bubble_sort(s,sz,sizeof(s[0]),cmp_stu_by_age);
}

int main()
{
    
    
	
	//test1();//排序整型数组
	//test2();排序float型数组
	//test3();//排序用结构体中的年龄进行比较
	//test4();//排序用结构体中的姓名进行比较,也就是按照字符串比较
	test5();
	test6();
	return 0;
}

库函数 qsort

qsort - 库函数 - p 排序
算法思想 quick sort 快速排序

void* 具体是什么

void* 具体是什么
int main()
{
    
    
	int a = 10;
	int* pa = &a;
	char* pa = &a; //这里从int*到char* 是不兼容的 

	void* p = &a;
	//void* 可以接收任意类型的地址
	//void* 类型的指针不能进行解引用的操作
	//void* 类型的指针不能进行+-整数的操作
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_52495715/article/details/120809231