Pregunta

¿Soy sólo yo o este código en Perlas de programación está mal (la clasificación rápida quiere 2 vacíos constantes, ¿no?) Si es así, ¿es correcta mi solución?Disculpas, recién estoy aprendiendo...

int wordncmp(char *p, char* q)
{   int n = k;
    for ( ; *p == *q; p++, q++)
        if (*p == 0 && --n == 0)
            return 0;
    return *p - *q;
}

int sortcmp(char **p, char **q)
{   return wordncmp(*p, *q);
}
...

qsort(word, nword, sizeof(word[0]), sortcmp);

¿Es esta una solución?

int sortcmp(const void *p, const void *q)
{   return wordncmp(* (char * const *) p, * (char * const *) q);
}
¿Fue útil?

Solución

El primer ejemplo de código probablemente funcionará con prácticamente cualquier compilador y CPU;sin embargo, es un comportamiento técnicamente indefinido, si se sigue el estándar C al pie de la letra.

Como usted ha dicho, el último argumento para qsort() es un puntero a una función que toma dos argumentos de tipo const void*. sortcmp toma diferentes argumentos.Tu compilador debería darle una advertencia sobre firmas de tipos incompatibles o algo así.En cualquier caso, se está realizando un casting de una función de un tipo a una función de otro tipo.

El estándar C especifica que puede convertir punteros de función a otros punteros de función con diferentes tipos, pero no puede desreferenciar e invocar el puntero de función convertido.Sin embargo, si vuelve a convertir el puntero de función a su tipo original, llamarlo tiene un comportamiento definido: llama a la función original.

Ya que estás lanzando desde un int (*)(char**, char**) a un int (*)(const void*, const void*), y luego eventualmente qsort() está invocando su función de comparación sin devolverla a int (*)(char**, char**), ese es un comportamiento indefinido.

Sin embargo, dado que prácticamente en todas las arquitecturas, un char ** y un const void* se representan de la misma manera, la llamada a la función casi siempre funcionará.

Si desea obtener un comportamiento definido, debe asegurarse de que su función de comparación tenga la firma de tipo adecuada y luego pueda convertir los argumentos al tipo adecuado.Su solución es exactamente correcta y no viola el estándar C allí.Bien hecho const-corrección: mucha gente no entiende exactamente qué char * const * medio.

También deberías hacer wordncmp() tomar parámetros de const char*, ya que no estás modificando los parámetros.

Nota al margen:Técnicamente, tampoco se puede convertir un puntero de función a un puntero de datos (p. ej.a void*) o viceversa.El estándar permite que los punteros de función y los punteros de datos tengan diferentes tamaños.Incluso si funciona en su computadora, no se garantiza que funcione siempre.

Otros consejos

Tiene usted razón, la firma de sortcmp no coincide con lo que qsort espera. Su corrección es correcta. wordcmp también debe hacerse const - correcta a medida que son técnicamente perdiendo algo de <=> -. Ness en el camino

int wordncmp(const char *p, const char* q)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top