[Advanced Pointer (3)] Callback function and qsort sort various types of data


foreword

The first two chapters talked about pointer types, array parameter passing and pointer parameter passing, as well as function pointers and function pointer arrays, and then the third chapter talked about callback functions


The great use of pointer functions is to implement callback functions

1. What is the callback function?

A callback function is a function called through a function pointer.

If a function pointer (address) is passed as a parameter to another function, when this pointer is used to call the function it points to, we say that this is a callback function. The callback function is not directly called by the implementer of the function, but is called by another party when a specific event or condition occurs, and is used to respond to the event or condition.

How to implement the callback function

The following code is too redundant.
If you package a function and call it, you can greatly reduce the workload of typing code. This function is a callback function.
insert image description here
So package a function called Calc, and call this function when using addition, subtraction, multiplication and division.

        case 1:
			Calc(Add);
			break;
		case 2:
			Calc(Sub);
			break;
		case 3:
			Calc(Mul);
			break;
		case 4:
			Calc(Div);
			break;

The function address is passed to the Calc function, and the function pointer is used to receive
this pf is a function pointer, the parameters pointed to are (int, int), and the return type is int

void Calc(int (*pf)(int, int))

The specific code is as follows

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 Div(int x, int y)
{
    
    
	return x / y;
}
void menu()
{
    
    
	printf("***************************\n");
	printf("*****  1.add  2.sub  ******\n");
	printf("*****  3.mul  4.div  ******\n");
	printf("*****  0.exit        ******\n");
	printf("***************************\n");
}
void Calc(int (*pf)(int, int))
{
    
                 
	int x = 0;
	int y = 0;
	int ret = 0;
	printf("请输入两个操作数:");
	scanf("%d %d", &x, &y);
	ret = pf(x, y);
	printf("ret = %d\n", ret);
}
int main()
{
    
    
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;
	do
	{
    
    
		menu();
		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;
}

The process is as follows:
insert image description here

Instead of calling the Add function directly, the Add function is passed to the pf pointer function, and the Add function is called through the pf function pointer to realize the calculation, then the pf function pointer is the callback function.

Function: The callback function is more extensive and versatile, and the code is not easy to write to death. If you call the Add function directly, the code will be fixed. If you want to call other functions, that code will not apply.

Second, the application of the callback function - qsort

qsort is a function in the standard library for sorting

How does the qsort function implement the callback function?

This has to talk about bubble sorting.
Generally, bubble sorting is written like this:

int main()
{
    
    
	int arr[10] = {
    
     9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	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];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
	for (i = 0; i < sz; i++)
	{
    
    
		printf("%d ", arr[i]);
	}
}

If you want to sort other types of data such as structures and floating-point types, there are certain problems with this code. It is only suitable for integer sorting, and the form is fixed, not flexible and not extensive.

So is there a way to write a sorting function that is applicable to any type?
The qsort function can solve this problem

qsort sorts various types of data

Features of qsort function
1. Quick sorting method
2. Suitable for sorting of any type of data

  1. Search for qsort on the cplusplus website, and you can see that qsort has four parameters:

insert image description here
The meaning of the four functions is:
void qsort(
void* base,//points to the first element of the array to be sorted
size_t num,//the number of elements to be sorted
size_t size,//the size of an element, in bytes
int(*cmp)(const void*, const void*)
);//function pointer type -The function pointed to by this function pointer can compare the two elements in the array pointed to by base


                      用qsort排序整型

According to the above four parameters, write the following code
insert image description here

  1. The last parameter is empty and not written, because some important knowledge points are involved here
    The fourth parameter is to write a function that can compare the two elements in the array pointed to by base and return the result.Then write a function called cmp_int, and the parameters are the two parameters given by the qsort function on the cplusplus website. insert image description here
    The code is as follows:
int cmp_int(const void* p1, const void* p2)
  1. After writing the function, how to compare two numbers?
    The calculation method found on the cplusplus website is as follows:
    insert image description here
    when the value pointed to by p1 is less than the value pointed to by p2, a number less than 0 is returned;
    when the value pointed to by p1 is equal to the value pointed to by p2, 0 is returned;
    when the value pointed to by p1 is greater than the value pointed to by p2 When the value of , returns a number greater than 0;

Then let the two numbers p1p2 make a difference, and return the result.

But here is also some knowledge involved:
A hot piece of knowledge:: A pointer to void* is a pointer with no concrete type.
A pointer of void* type can receive any type of address

The advantage of using void* in the function parameter is that it is universal and can accept any type of data sorting, and programming will not give a warning.
But pointers of this type cannot be dereferenced directly, nor can pointer arithmetic be performed directly. So when comparing the size of two numbers, type conversion is required.
It means that what type is to be sorted, the type of forced type conversion.
For example: when comparing integer data, p1 and p2 must be forced to convert to integer; when comparing floating-point data, p1 and p2 must be forced to convert to float point type.

code show as below:

int cmp_int(const void* p1, const void* p2)
{
    
    
	return (*(int*)p1 - *(int*)p2);
}
  1. Finally, print out the result and
    pack a print function.
    The parameters are an integer array and the size of the array,
    and print each element in a loop.
void print(int arr[], int sz)
{
    
    
	int i = 0;
	for (i = 0; i < sz; i++)
	{
    
    
		printf("%d ", arr[i]);
	}
}

The complete code is as follows:

#include<stdlib.h>
int cmp_int(const void* p1, const void* p2)
{
    
    
	return (*(int*)p1 - *(int*)p2);
}
void print(int arr[], int sz)
{
    
    
	int i = 0;
	for (i = 0; i < sz; i++)
	{
    
    
		printf("%d ", arr[i]);
	}
}
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);
	print(arr, sz);
}
int main()
{
    
    
	test1();
	return 0;
}

Note: The header file for the qsort function is#include<stdlib.h>


                     用qsort 排序结构体

age comparison

#include<stdio.h>
#include<stdlib.h>
struct Stu
{
    
    
	char name[20];
	int age;
};
int cmp_stu_by_age(const void* p1, const void* p2)
{
    
    
	return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age;
}

void print(struct Stu arr[], int sz)
{
    
    
	int i = 0;
	for (i = 0; i < sz; i++)
	{
    
    
		printf("%d ", arr[i].age);
	}
}
void test2()
{
    
    
	struct Stu arr[] = {
    
     {
    
    "zhangsan",20},{
    
    "lisi",50},{
    
    "wangwu",15} };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_age);
	print(arr,sz);
}
int main()
{
    
    
	test2();
	return 0;
}

name comparison size

#include<stdio.h>
#include<stdlib.h>
struct Stu

{
    
    
	char name[20];
	int age;
};

int cmp_str_stu_by_name(const void* p1, const void* p2)

{
    
    
	return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}
//名字比较不能相减,名字是字符串,字符串比较大小用strcmp

void print(struct Stu arr[], int sz)
{
    
    
	int i = 0;
	for (i = 0; i < sz; i++)
	{
    
    
		printf("%s ", arr[i].name);
	}
}
void test3()

{
    
    
	struct Stu arr[] = {
    
     {
    
    "zhangsan",50},{
    
    "lisi",15},{
    
    "wangwu",30} };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), cmp_str_stu_by_name);
	print(arr, sz);
}

Summarize

This chapter talks about the meaning of the callback function , how to implement the callback function and qsort to sort various types of data, I hope it will be helpful to you!

Guess you like

Origin blog.csdn.net/2301_76496134/article/details/131809245