Verwendung von qsort für das Zeichen-Array in C

8

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:

%Vor%

Ausgaben: dabce wenn ich abcde erwarte.

    
user1527227 18.04.2014, 04:52
quelle

3 Antworten

7

Einfacher Fehler.

Verwenden Sie char* anstelle von int* in cmpfunc .

%Vor%

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

sein, wenn ein *(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.

    
R Sahu 18.04.2014, 04:59
quelle
3

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.

    
caskey 18.04.2014 05:00
quelle
0

Das Problem liegt in der Vergleichsfunktion comfunc mit dem Operator type cast.

%Vor%

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

geändert %Vor%

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

geändert werden %Vor%

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

aufrufen %Vor%     
ajay 18.04.2014 05:09
quelle

Tags und Links