c语言从入门到实战——回调函数与qsort的讲解和模拟实现

回调函数与qsort的讲解和模拟实现

  • 前言
  • 1. 回调函数是什么?
  • 2. qsort
    • 2.1 使用qsort函数排序整型数据
    • 2.2 使用qsort排序结构数据
  • 3. qsort函数的模拟实现


前言

回调函数是一个函数,它作为参数传递给另一个函数,并且能够在该函数内部被调用。在C语言中,回调函数通常被用于实现事件处理和排序算法中。

qsort是C标准库中的一个排序函数,它可以对任意类型的数组进行排序。qsort需要三个参数:要排序的数组、数组元素的个数和一个指向回调函数的指针。回调函数必须满足两个条件:能够比较数组中的元素,返回一个整数表示它们之间的大小关系;并且它应该能够被qsort函数调用。


1. 回调函数是什么?

C语言中,回调函数是指将一个函数作为参数传递给另一个函数,并在后者中被调用的函数。

一般情况下,回调函数被用来在程序中实现事件处理和消息传递等机制。例如,当一个用户在应用程序中点击一个按钮时,应用程序会调用相应的回调函数来处理该事件。

以下是一个示例代码,展示了如何在C语言中定义和使用回调函数:

#include 

// 回调函数定义
typedef int (*callback)(int);

// 回调函数实现
int callback_function(int num) {
    return num * 2;
}

// 接收回调函数参数的函数
void accept_callback(int num, callback cb) {
    int result = cb(num); // 调用回调函数
    printf("The result is: %d\n", result);
}

int main() {
    // 调用 accept_callback 函数,并传入回调函数指针
    accept_callback(5, callback_function);

    return 0;
}

在上述示例中,我们通过定义 callback 类型为函数指针类型,从而定义了一个回调函数类型。接着,我们定义了回调函数 callback_function,该函数接收一个整数作为参数,并返回该参数的两倍。最后,我们通过调用 accept_callback 函数,并传入一个整数以及回调函数的指针,实现了回调函数的调用和结果输出。

需要注意的是,回调函数的实现和使用需要满足一定的约定,例如回调函数的参数和返回值类型需要与被调用函数的要求一致,否则会导致程序运行错误。

回调函数就是一个通过函数指针调用的函数。

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

//使用回调函数改造前
#include 
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", r
	break;
	case 2:
	printf("输入操作数:");
	scanf("%d %d", &x, &y)
	ret = sub(x, y);
	printf("ret = %d\n", r
	break;
	case 3:
	printf("输入操作数:");
	scanf("%d %d", &x, &y)
	ret = mul(x, y);
	printf("ret = %d\n", r
	break;
	case 4:
	printf("输入操作数:");
	scanf("%d %d", &x, &y)
	ret = div(x, y);
	printf("ret = %d\n", r
	break;
	case 0:
	printf("退出程序\n");
	break;
	default:
	printf("选择错误\n");
	break;
	}
	} while (input);
	return 0;
}
//使用回到函数改造后
#include 
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;
	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

c语言从入门到实战——回调函数与qsort的讲解和模拟实现_第1张图片
![在这里插入图片描述](https://img-blog.csdnimg.cn/a775e1216eb84ac0b69764becda26310.png
c语言从入门到实战——回调函数与qsort的讲解和模拟实现_第2张图片
)

qsort是C语言中的一个标准库函数,用于实现快速排序算法。它可以对任意类型的数组进行排序,只需要给出相应的比较函数即可。

qsort的函数原型如下:

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

其中,base是要排序的数组的首地址,nmemb是数组中元素的个数,size是每个元素的大小(以字节为单位),compar是用来比较数组中元素大小的函数指针。

比较函数的定义如下:

int compar(const void *a, const void *b);

函数需要返回一个整型值,表示两个元素的大小关系。如果a小于b,返回一个负数;如果a等于b,返回0;如果a大于b,返回一个正数。

下面是一个使用qsort进行int类型数组排序的例子:

#include 
#include 

int cmp(const void *a, const void *b) {
    return *(int *)a - *(int *)b;
}

int main() {
    int arr[] = {3, 1, 4, 1, 5, 9, 2, 6};
    int n = sizeof(arr) / sizeof(int);

    qsort(arr, n, sizeof(int), cmp);

    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}
运行结果为:1 1 2 3 4 5 6 9

上述代码中,我们定义了一个比较函数cmp,返回a-b的结果,然后将其传给qsort函数进行排序。在main函数中,我们定义了一个int类型的数组arr,调用qsort进行排序后,输出结果即可。

需要注意的是,qsort函数是一个不稳定的排序算法,即排序后可能改变数组中相同元素的原有顺序。

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

#include 
//qosrt函数的使用者得实现一个比较函数
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排序结构数据

#include 
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(采用冒泡的方式)。

#include  
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 )(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);
			}
		}
	}
}
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;
}

你可能感兴趣的:(C语言从入门到实战,c语言,算法,开发语言,程序员创富,学习方法,程序人生,visual,studio)