sirven que punteros parametros para operaciones los funciones estructura ejemplos datos con como cadenas arreglos aritmetica apuntadores c sorting qsort double-pointer

que - ¿Cómo qsort una matriz de punteros a char en C?



punteros en c ejemplos (7)

Supongamos que tengo una serie de punteros a char en C:

char *data[5] = { "boda", "cydo", "washington", "dc", "obama" };

Y deseo ordenar esta matriz usando qsort:

qsort(data, 5, sizeof(char *), compare_function);

No puedo llegar a la función de comparación. Por alguna razón esto no funciona:

int compare_function(const void *name1, const void *name2) { const char *name1_ = (const char *)name1; const char *name2_ = (const char *)name2; return strcmp(name1_, name2_); }

Hice mucha búsqueda y descubrí que tenía que usar ** dentro de qsort:

int compare_function(const void *name1, const void *name2) { const char *name1_ = *(const char **)name1; const char *name2_ = *(const char **)name2; return strcmp(name1_, name2_); }

Y esto funciona.

¿Alguien puede explicar el uso de *(const char **)name1 en esta función? No lo entiendo en absoluto. ¿Por qué el doble puntero? ¿Por qué no funcionó mi función original?

Gracias, Boda Cydo.


@bodacydo aquí es un programa que puede explicar lo que otros programadores están tratando de transmitir, pero esto sería en el contexto de "enteros"

#include <stdio.h> int main() { int i , j; int *x[2] = {&i, &j}; i = 10; j = 20; printf("in main() address of i = %p, address of j = %p /r/n", &i, &j); fun(x); fun(x + 1); return 0; } void fun(int **ptr) { printf("value(it would be an address) of decayed element received = %p, double dereferenced value is %d /r/n",*ptr, **ptr); printf("the decayed value can also be printed as *(int **)ptr = %p /r/n", *(int **)ptr ); }


Imagina que tus datos son datos double data[5] .

Su método de comparación recibiría punteros (double *, pasados ​​como void *) a los elementos (double).
Ahora reemplaza doble con char * otra vez.


La función de comparación lleva los punteros al tipo de objeto que está en la matriz que desea ordenar. Como la matriz contiene char * , su función de comparación lleva los punteros a char * , también conocido como char ** .


Si ayuda a mantener las cosas claras en su cabeza, el tipo al que debe enviar los punteros en su comparador es el mismo que el tipo original del puntero de datos que pasa a qsort (que la base llamadas qsort docs). Pero para que qsort sea ​​genérico, solo maneja todo como void* , independientemente de lo que "realmente" es.

Entonces, si estás ordenando una serie de entradas, entonces pasarás un int* (convertido a void* ). qsort le devolverá dos punteros void* al comparador, que usted convierte a int* , y la desreferencia para obtener los valores int que realmente compara.

Ahora reemplace int con char* :

si está ordenando una matriz de caracteres char* , entonces pasará un char** (convertido a void* ). qsort le devolverá dos punteros void* al comparador, que usted convierte a char** , y la desreferencia para obtener los valores de char* que realmente compara.

En su ejemplo, debido a que está usando una matriz, el char** que usted pasa es el resultado de la matriz de char* "decae" a un puntero a su primer elemento. Dado que el primer elemento es un char* , un puntero a él es un char** .


del man qsort :

The contents of the array are sorted in ascending order according to a comparison function pointed to by compar, which is called with two arguments that **point** to the objects being compared.

Así que suena como que la función de comparación obtiene punteros a los elementos de la matriz. Ahora, un puntero a un char * es un char ** (es decir, un puntero a un puntero a un carácter).


char *data[5] = { "boda", "cydo", "washington", "dc", "obama" };

es una declaración que solicita al compilador una matriz de tamaño 5 de punteros de caracteres. Has inicializado esos punteros a cadenas literales, pero para el compilador, sigue siendo una matriz de cinco punteros.

Cuando se pasa esa matriz a qsort , la matriz de punteros decae en un puntero que apunta al primer elemento, de acuerdo con las reglas de paso de parámetros de la matriz C.

Por lo tanto, debe procesar un nivel de indirección antes de poder llegar a las matrices de caracteres reales que contienen las constantes.


qsort es lo suficientemente general para ordenar matrices que consisten en otras cosas además de punteros. Es por eso que el parámetro de tamaño está ahí. No puede pasar los elementos de la matriz a la función de comparación directamente, ya que no sabe en el momento de la compilación qué tan grandes son. Por eso pasa punteros. En tu caso obtienes punteros a char * , char ** .