C语言指针详解4

一.回调函数

回调函数就是通过函数指针调用的函数。如果把函数指针作为参数传递给另外一个函数,当这个指针被用来调用其所指向的函数时,被调用的函数就是回调函数。回调函数不是有该函数的实现方(谁写出函数内部完整执行逻辑,谁就是该函数的实现方;只拿来调用、不写内部代码的是调用方。)直接调用,而是在特定的时间或条件发生时由另一方调用。

示例:

复制代码
#include <stdio.h>


int calculate(int a, int b, int (*cb)(int, int))
{
    return cb(a, b);
}

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 main()
{
    int a = 10, b = 3;
    printf("加法:%d\n", calculate(a, b, add));
    printf("减法:%d\n", calculate(a, b, sub));
    printf("乘法:%d\n", calculate(a, b, mul));
    return 0;
}

在这段代码中,add,sub,mul是函数的实现方,他们定义完了之后并没有在实现方(及函数内部)直接调用,而是在caculate中被函数指针cb调用,所以他们三个是回调函数。

二.qsort函数的使用

qsort是一个库函数,是用来对数据进行排序的,qsort函数能排序任意类型的数据,它是基于快速排序的思想进行排序的。对应的头文件是<stdlib.h>

函数原型:

void qsort(void *base, size_t num, size_t size, int (*compar)(const void *, const void *));

1.base:待排序的首地址元素。

2.num:数组元素个数

3.size:单个元素占用字节元素大小

4.函数指针:比较函数。

5.比较函数:int cmp(const void *a, const void *b)

6.降序只需交换a,b:return *(int*)b - *(int*)a;

示例

复制代码
#include <stdio.h>
#include <stdlib.h>

// 整型升序比较函数
int cmp_int(const void* a, const void* b)
{
    // 强制转int*解引用相减
    return *(int*)a - *(int*)b;
}

int main()
{
    int arr[] = { 5, 2, 9, 1, 5, 6 };
    int len = sizeof(arr) / sizeof(arr[0]);

    qsort(arr, len, sizeof(int), cmp_int);

    for (int i = 0; i < len; i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}
复制代码
三.模拟实现(冒泡排序):
复制代码
#include <stdio.h>

void Swap(char* buf1, char* buf2,size_t width)
{
	size_t i = 0;
	for (i = 0; i < width; i++)
	{
		char tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++;
		buf2++;

	}
}

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

void bubble_sort(void* base,size_t sz,size_t width,int (*cmp) (const void* p1,const void *p2))
//参数:1.排序的数组。2.数组长度。3.数组中每个元素的大小(字节数)4.比较函数-函数指针
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			//下标为j和j+1这两个元素
			//升序
			if (cmp((char*)base + j * width,(char*)base + (j + 1)* width )> 0)
			{
				//交换
				Swap((char*)base + j * width, (char*)base + (j + 1) * width,width);
			}
		}
	}
}


int print_arr(int* arr,int sz)
{
	int i = 0;
	//确定趟数
	for (int i = 0; i < sz - 1; i++)
	{
		printf("%d ",arr[i]);
	}
	printf("\n");
}

void test()
{
	int arr[] = { 8,7,6,5,4,3,2,9,1,0 };//0 1 2 3 4 5 6 7 8 9
	//对数组进行排序 - 升序
	int sz = sizeof(arr) / sizeof(arr[0]);
	print_arr(arr, sz);
	bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
	print_arr(arr, sz);
}

int main()
{
	test();
	return 0;
}