[Lenguaje C] Función de devolución de llamada, el uso de la función de clasificación qsort y su propia implementación, explicación súper detallada


inserte la descripción de la imagen aquí
Primer registro que el número de visitas ha superado las 2000, ¡gracias por su apoyo! ! !
Aquí está el enlace avanzado del puntero anterior, que es conveniente para que todos lo vean: Agregar descripción del enlace

prefacio

Hola a todos, hoy me gustaría compartir el contenido restante del último número de punteros avanzados: la función de devolución de llamada, esto es muy importante, ¡aprendamos a entenderlo juntos! ! !


1. ¿Qué es la función de devolución de llamada?

Concepto estándar:
una función de devolución de llamada es una función llamada a través de un puntero de función. Si pasa un puntero de función (dirección) como parámetro a otra
función, cuando este puntero se usa para llamar a la función a la que apunta, decimos que se trata de una función de devolución de llamada.
El implementador de la función no llama directamente a la función de devolución de llamada , sino que la llama otra parte cuando ocurre un evento o condición específicos, y se usa para responder al evento o condición
.

En pocas palabras: una función llamada por un puntero de función en otra función se llama función de devolución de llamada

En segundo lugar, el uso de la función de devolución de llamada.

1. Use la función qsort en la biblioteca estándar

La función qsort no solo puede ordenar matrices enteras, sino también tipos de datos como estructuras

el código se muestra a continuación:

#include <stdio.h>
//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);
    //qsort的第一个参数是排序数组的首元素地址
    //第二个参数是排序的长度
    //第三个参数是每个元素的大小
    //第四参数是使用者自己写的排序依据函数的地址(这里就是使用回调函数)
    for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++)
   {
    
    
       printf( "%d ", arr[i]);
   }
    printf("\n");
    return 0;
}

La pantalla de resultados en ejecución de la ordenación de matrices enteras:
inserte la descripción de la imagen aquí

2. Use la función qsort para ordenar la matriz de estructura

Primero mira el código de la siguiente manera:

#include<stdio.h>
#inlcude<string.h>
struct stu {
    
    
	int age;
	char name[20];
	double score;
};
//依据年龄大小排序的比较函数
int compar_by_age(const void* e1, const void* e2)
{
    
    
	return ((struct stu*)e1)->age - ((struct stu*)e2)->age;
}
//依据名字排序的比较函数
int compar_by_name(const void* e1, const void* e2)
{
    
    
	return strcmp(((struct stu*)e1)->name, ((struct stu*)e2)->name);
}
int main()
{
    
    
//这是定义一个结构体类型的数组
	struct stu S[3] = {
    
     {
    
    21,"FRH",100},{
    
    19,"MSY",90},{
    
    18,"LZY",85} };
	int Ssz = sizeof(S) / sizeof(S[0]);
	qsort(S, Ssz, sizeof(S[0]), compar_by_age);
	qsort(S, Ssz, sizeof(S[0]), compar_by_name);
	return 0;
}

Comparación de resultados antes y después de ordenar:
Este es el orden de la matriz de estructura antes de ordenar:
inserte la descripción de la imagen aquí
Este es el orden después de ordenar por edad:
inserte la descripción de la imagen aquí
Este es el orden después de ordenar por nombre:
inserte la descripción de la imagen aquí

Tercero, realiza la función qsort

Primero echemos un vistazo a la apariencia de la función qsort en la biblioteca estándar:
inserte la descripción de la imagen aquí
no tiene valor de retorno y los cuatro parámetros son:
1. El primer parámetro de qsort es la dirección del primer elemento de la matriz ordenada
2. El el segundo parámetro es la longitud de la clasificación
3. El tercer parámetro es el tamaño de cada elemento
4. El cuarto parámetro es la dirección de la función de clasificación escrita por el usuario (aquí está la función de devolución de llamada)

作者是依据冒泡排序实现的qosrt函数,我们之间上代码:
#include<stdio.h>
#inlcude<string.h>
//依据名字排序的比较函数
int compar_by_name(const void* e1, const void* e2)
{
    
    
	return strcmp(((struct stu*)e1)->name, ((struct stu*)e2)->name);
}
//依据整型大小排序的比较函数
int int_cmp(const void * p1, const void * p2)
{
    
    //这里都会将接收到的地址转换为所需要比较的类型
  return (*( int *)p1 - *(int *) p2);
}

//这里排序中交换两个元素的交换函数
void Swap(char* x, char* y,int size)
{
    
    
//利用char* 接收需要交换的元素,可以保证对其每个字节进行交换从而实现整体全部字节的交换
//size就是该元素所占字节的大小,决定每次交换循环几次
	int i = 0;
	for (i = 0; i < size; i++)
	{
    
    
		char temp = *x;
		*x = *y;
		*y = temp;
		x++;
		y++;

	}
}

void Bubble_Sort(void* base, size_t num, size_t size,int (*compar)(const void*, const void*))
{
    
    
	int i = 0;
	for (i = 0; i < num - 1; i++)
	{
    
    
		int j = 0;
		for (j = 0; j < num - 1 - i; j++)
		{
    
    
		//为什么要将首元素地址转换为char* 类型呢?
		//因为:这样可以保证任何类型数组在排序比较时能够访问到其中的每一个元素
		//这个设计是真的巧妙
			if (compar(((char*)base + j * size), ((char*)base + (j+1)*size))>0)
			{
    
    
				Swap(((char*)base + j * size), ((char*)base + (j+1)*size), size);
			}
		}
	}
}

Pruébalo:

int main()
{
    
    
	int arr[10] = {
    
     9,8,7,6,5,4,3,2,1,0 };
	struct stu S[3] = {
    
     {
    
    21,"FRH",100},{
    
    19,"MSY",90},{
    
    18,"LZY",85} };
	int Ssz = sizeof(S) / sizeof(S[0]);
	int sz = sizeof(arr) / sizeof(arr[0]);
	Bubble_Sort(arr,sz,sizeof(arr[0]),compar_by_int);
	Print(arr, sz);
	Bubble_Sort(S, Ssz, sizeof(S[0]), compar_by_age);
	Bubble_Sort(S, Ssz, sizeof(S[0]), compar_by_name);
	return 0;
}

Se puede obtener que el resultado de la clasificación es el mismo que el resultado de llamar a la función qsort en la biblioteca de anotaciones anterior
inserte la descripción de la imagen aquí

Resumir

Este es el final de compartir la función de devolución de llamada. Espero que la función qsort pueda ayudar a todos. El blogger siente que es realmente útil. La usaré tanto como sea posible en el futuro. Espero que este artículo pueda ayudar a todos. . ¡Gracias por leer! ! !

Supongo que te gusta

Origin blog.csdn.net/m0_71214261/article/details/132272332
Recomendado
Clasificación