Pergunta

é só eu ou esse código em Programação Pérolas está errado (quicksort quer 2 vazios const, não?) Se assim for, é a minha solução certa? Desculpas, apenas aprender ...

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);

Isto é uma solução?

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

Solução

O primeiro exemplo de código irá provavelmente trabalhar com praticamente qualquer compilador e CPU; no entanto, é o comportamento tecnicamente indefinido, se você seguir o padrão C para a carta.

Como você disse, o último argumento para qsort() é um ponteiro para uma função que toma dois argumentos do tipo const void*. sortcmp leva argumentos diferentes. Seu compilador deve dar-lhe um aviso sobre assinaturas de tipo incompatíveis ou algo assim. Em qualquer caso, um molde está a ser realizada a partir de uma função de um tipo de uma função de um outro tipo.

Os especifica C padrão que você pode lançar ponteiros de função para outros ponteiros de função com diferentes tipos, mas você não pode excluir a referência e invocar o ponteiro de função fundido. No entanto, se você re-converter o ponteiro de volta função para seu tipo original, em seguida, chamar esse comportamento definiu -. Ele chama a função original

Desde que você está fundição de um int (*)(char**, char**) a um int (*)(const void*, const void*) e, eventualmente, qsort() está invocando a sua função de comparação sem convertê-lo de volta para int (*)(char**, char**), isso é um comportamento indefinido.

No entanto, uma vez que praticamente em todas as arquiteturas, um char ** e uma const void* são representados da mesma forma, a chamada de função será praticamente sempre trabalho.

Se você deseja obter um comportamento definido, você tem que se certificar de sua função de comparação tem a assinatura de tipo apropriado, e, em seguida, você pode lançar os argumentos para o tipo adequado. Sua solução é exatamente correto e não viola o padrão C lá. Bem feito em const-correção -. Um monte de pessoas não entendem exatamente o que significa char * const *

Você também deve fazer parâmetros wordncmp() à recolha de const char*, desde que você não está modificando os parâmetros.

Nota lateral: Também é tecnicamente não pode converter um ponteiro função de um ponteiro de dados (por exemplo, um void*) ou vice-versa. A norma permite ponteiros de função e ponteiros de dados para ter tamanhos diferentes. Mesmo se ele funciona no seu computador, não é garantida para sempre trabalho.

Outras dicas

Você está correto, a assinatura para sortcmp não corresponde ao que espera qsort. Sua correção é certo. wordcmp também deve ser feita const-correto como você está tecnicamente perder algum do const-ness ao longo do caminho.

int wordncmp(const char *p, const char* q)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top