Domanda

Sono solo io o questo codice in Programmazione Perle è sbagliato (quicksort vuole 2 vuoti const, no?) In caso affermativo, è la mia soluzione giusta? Ci scusiamo, solo l'apprendimento ...

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

Si tratta di una soluzione?

int sortcmp(const void *p, const void *q)
{   return wordncmp(* (char * const *) p, * (char * const *) q);
}
È stato utile?

Soluzione

Il primo esempio di codice sarà probabilmente funzionerà con qualsiasi compilatore e CPU; tuttavia, è un comportamento tecnicamente definito, se si segue lo standard C alla lettera.

Come hai detto, l'ultimo argomento a qsort() è un puntatore a una funzione di prendere due argomenti di tipo const void*. sortcmp prende argomenti diversi. Il compilatore dovrebbe dare un avvertimento circa le firme di tipo incompatibili o qualcosa del genere. In ogni caso, un calco viene eseguita da una funzione di un tipo a una funzione di un altro tipo.

Lo standard C specifica che si può lanciare puntatori alle funzioni ad altri puntatori a funzione con diversi tipi, ma non puoi dereference e richiamare il puntatore a funzione fuso. Tuttavia, se si ri-cast del puntatore a funzione al suo tipo di originale, quindi chiamando quel comportamento ha definito -. Esso chiama la funzione originale

Dato che si sta gettando da un int (*)(char**, char**) ad un int (*)(const void*, const void*), e poi alla fine char ** sta invocando la funzione di confronto, senza lanciare di nuovo a const, questo è un comportamento indefinito.

Tuttavia, dal momento che praticamente su tutte le architetture, un char * const * e wordncmp() sono rappresentati allo stesso modo, la chiamata di funzione sarà quasi sempre funziona.

Se si desidera ottenere un comportamento definito, è necessario assicurarsi che la vostra funzione di confronto ha la firma di tipo corretto, e quindi si può lanciare gli argomenti al tipo corretto. La soluzione è esattamente corretto e non viola lo standard C lì. Complimenti a const char* - correttezza -. Un sacco di gente non capisce esattamente cosa void* mezzi

Si dovrebbe anche fare <=> prendere parametri di <=>, dal momento che non sta modificando i parametri.

Nota a margine: È anche tecnicamente non può lanciare un puntatore alla funzione a un puntatore di dati (per esempio un <=>) o viceversa. Lo standard consente di puntatori a funzione e puntatori di dati per avere dimensioni diverse. Anche se funziona sul vostro computer, non è garantito il funzionamento sempre.

Altri suggerimenti

Lei ha ragione, la firma per sortcmp non corrisponde a ciò che si aspetta qsort. La correzione è di destra. wordcmp dovrebbe anche essere fatto const - corretta, come si sta tecnicamente perdendo alcuni dei <=> -. Ness lungo la strada

int wordncmp(const char *p, const char* q)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top