Ich versuche mit qsort
ein Zeichenarray zu sortieren. Ich kann nicht sehen, warum das nicht funktioniert. Ich habe einen Zeiger auf die Vergleichsfunktion, wie die man
Seiten angibt. Kann mir bitte jemand sagen, was los ist? Vielen Dank. Mein Code:
Ausgaben: dabce
wenn ich abcde
erwarte.
Einfacher Fehler.
Verwenden Sie char*
anstelle von int*
in cmpfunc
.
Wenn Sie int*
anstelle von char*
verwenden, wird die Adresse, auf die a
zeigt, als Adresse für ein int
interpretiert, nicht für ein char
.
Ihre Eingabe hat die folgenden Zeichen:
%Vor%Im Hex sind das:
%Vor% Wenn Sie die Adressen behandeln, die auf a
und b
als int*
verweisen, kann int
entweder
*(int*)a
4 Bytes in Ihrem System benötigt
%Vor%
oder
%Vor%abhängig davon, ob Sie ein Big-Endian-System oder ein kleines Endian-System haben.
Sie können in ähnlicher Weise berechnen, was *(int*)b
wäre. Wie Sie sehen können, stoßen Sie bereits auf unerwartete Zahlenvergleiche. Wenn Sie mit dem Vergleichen der Werte beginnen, die sich an anderen Bytepositionen Ihrer Eingabe befinden, verwenden Sie auch Speicher, den Sie nicht verwenden sollten, und Sie erreichen die Bereiche von undefiniertem Verhalten.
Sie haben hier mindestens zwei Probleme.
Zuerst versuchen Sie, den Inhalt eines statisch definierten Literals zu sortieren, das der Compiler in unveränderlichem RAM speichern kann.
Zweitens, und das Wichtigste ist, dass Sie das void * in Ihrer Vergleichsfunktion in ein int * umwandeln. Wenn Sie sizeof(int) == 4
und sizeof(char) == 1
annehmen, vergleichen Sie effektiv die Zeichen 0-3 "als ganze Zahl" mit den Zeichen 1-4 "als ganze Zahl".
Im Falle von sizeof(int) = 8
(d. h. 64-Bit-Compilern) würden Sie es noch schlechter machen. Wirf die void*
auf char*
und du solltest in Ordnung sein.
Das Problem liegt in der Vergleichsfunktion comfunc
mit dem Operator type cast.
Wenn Sie den void-Zeiger a
auf int *
setzen und dann deneferenzieren, bedeutet dies, dass er die sizeof(int)
-Bytes vom Anfang der in a
enthaltenen Adresse liest. Der Ausdruck in der return-Anweisung vergleicht also die sizeof(int)
Anzahl der Bytes von der Adresse in a
mit der sizeof(int)
Anzahl der Bytes von der Adresse in b
, anstatt die Zeichen an den Adressen zu vergleichen Zeiger a
und b
. Um dies zu veranschaulichen, habe ich die Vergleichsfunktion zu
Und das ist die Ausgabe, die ich bekomme
%Vor% Sie können den Unterschied in den Werten sehen, die gelesen werden, wenn der Vergleich nach der Typumwandlung in int *
und nach der Typumwandlung in char *
durchgeführt wird. Die Vergleichsfunktion sollte in
Außerdem müssen Sie das Ergebnis von strlen
function und sizeof
nicht umsetzen, da sie bereits Werte vom Typ size_t
zurückgeben. Außerdem ist es besser lesbar und wartbar, sizeof
für das Array-Element zu verwenden. Sie sollten einfach qsort
als