Comparación genérica
Parte de la sección Object Oriented Programming del Journey de C de Coddy — lección 52 de 61.
Funciones genéricas como qsort y bsearch en la biblioteca estándar de C necesitan una forma de comparar elementos sin conocer sus tipos. La solución es una función de comparación — una función que tú escribes y que el algoritmo genérico llama cada vez que necesita comparar dos elementos.
La firma estándar para las funciones de comparación es:
int compare(const void* a, const void* b);Ambos parámetros son const void* porque la función genérica no sabe qué tipo está ordenando. El valor de retorno sigue una convención específica:
| Valor de retorno | Significado |
|---|---|
| Negativo | a va antes que b |
| Cero | a es igual a b |
| Positivo | a va después de b |
Dentro de tu función de comparación, conviertes los punteros void* al tipo real y comparas los valores. Aquí se muestra cómo comparar enteros:
int compare_ints(const void* a, const void* b) {
int val_a = *(const int*)a;
int val_b = *(const int*)b;
return val_a - val_b;
}El truco de la resta funciona bien para los enteros: si a es menor, el resultado es negativo; si es igual, cero; si es mayor, positivo. Esta función ahora se puede pasar a qsort para ordenar un array de enteros en orden ascendente.
Desafío
FácilEscribe una función compare_ints que compare dos enteros siguiendo la convención estándar de funciones de comparación utilizada por algoritmos genéricos como qsort.
Tu función debe comparar los dos valores y devolver un resultado que indique su relación de orden.
Convención del Valor de Retorno:
- Devuelve un valor negativo si el primer entero va antes que el segundo (first < second)
- Devuelve cero si ambos enteros son iguales
- Devuelve un valor positivo si el primer entero va después que el segundo (first > second)
Parámetros:
a(int): El primer entero a compararb(int): El segundo entero a comparar
Devuelve: Un entero que indica el orden: negativo si a < b, cero si a == b, positivo si a > b.
Pista: El truco de la resta de la lección proporciona una solución elegante de una sola línea.
Hoja de referencia
Las funciones de comparación permiten que algoritmos genéricos como qsort y bsearch comparen elementos sin conocer sus tipos.
La firma estándar para las funciones de comparación:
int compare(const void* a, const void* b);Los parámetros son const void* porque la función genérica no conoce el tipo que se está ordenando.
Convención del valor de retorno:
| Valor de retorno | Significado |
|---|---|
| Negativo | a va antes que b |
| Cero | a es igual a b |
| Positivo | a va después de b |
Dentro de la función de comparación, convierta (cast) los punteros void* al tipo real y compare los valores:
int compare_ints(const void* a, const void* b) {
int val_a = *(const int*)a;
int val_b = *(const int*)b;
return val_a - val_b;
}El truco de la resta funciona para enteros: si a es menor, el resultado es negativo; si es igual, cero; si es mayor, positivo.
Pruébalo tú mismo
int compare_ints(int a, int b) {
// Escribe el código aquí
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Object Oriented Programming
1Fundamentos de programación modular
Archivos de cabeceraGuardas de inclusiónArchivos fuenteFunciones estáticasRepaso: Calculadora modular4Encapsulamiento
Concepto de punteros opacosDefinición de structs opacosGetters y SettersValidación en settersResumen: Caja secreta7Punteros a funciones
Declaración de punteros a funcionesLlamada a punteros a funcionesTypedef para punteros a funcionesPasar funciones como argumentosRepaso: Dispatch de calculadora10Contenedores genéricos
Repaso de punteros voidWrapper genéricoSwap genéricoComparación genéricaRepaso: Array genérico2Objetos y métodos
Structs como objetosEl puntero 'Self'Const CorrectnessPuntero vs. ValorMétodos auxiliaresResumen: Point Manager5Proyecto: Cuenta bancaria simple
Configuración del proyectoImplementación de la cuenta3Ciclo de vida de los objetos
Patrón ConstructorPatrón DestructorInicialización en StackCopia profundaResumen: String Wrapper6Herencia mediante composición
Incrustación de StructsLa regla del primer miembroAcceso a miembros padreUpcastingResumen: Jerarquía de formas9Proyecto: Dibujador de figuras
Descripción general del proyectoImplementación del círculo