2012-03-23 2 views
3

Ich versuche, die c-Bibliothek qsort im Kontext der Zeiger auf Strukturen zu verstehen. Hier ist der vorhandene Code, Ich mag würde manipulieren:mit einem qsort, um struct Zeiger mit verschiedenen Variablen zu sortieren

Die Struktur:

#define MAX_NAME 20 
#define NUM_MONTHS 12 

typedef struct EMP { 
    char name[MAX_NAME+1]; 
    int monthSales[NUM_MONTHS]; 
    int total; 
} Emp; 

Die globale Initialisierung der Daten und ihre Größe:

Emp *data;//where all entries are kept 
int empSize; 

und ich aufgebaut haben 2-Arrays von EmP-Zeigern, die ich gerne auf die Daten in verschiedenen Aufträgen beziehen würde:

Emp *nameArray[empSize];//an array of pointers to point to entries alphabetically 
Emp *salesArray[empSize]; //an array of pointers to pointing to entries by sales 

Nachdem sie identisch zugewiesen wurden, möchte ich sie mit einem qsort anders anordnen. der Namearray alphabetisch, den Namen in der Struktur und die salesArray größten zur kleinsten verwenden, die insgesamt in der Struktur mit

Was die Methoden und die qsort Argumente aussehen vergleichen sollte?

Dank

+0

ist diese Hausaufgabe? Es scheint die Art von Frage zu sein, die ich mir gestellt habe, als ich im Bildungsbereich arbeitete. – gbulmer

+0

Wie sieht Ihr Code aus, der versucht, eines der Arrays zu sortieren? Haben Sie mit einer Reihe von Emp-Daten [empSize] begonnen, um es ein bisschen einfacher zu machen, sich damit abzufinden? Ich würde mit einem Array der Strukturen beginnen, das funktioniert und dann das Array von Zeigern verwenden. Schreiben Sie dann die zweite Vergleichsfunktion und verwenden Sie das zweite Array von Zeigern. – gbulmer

Antwort

3

Sie müssen nur zwei Funktionen unterschiedliche Vergleich zu definieren. Jede Vergleichsfunktion sollte zwei Zeiger auf void einbeziehen (in diesem Fall würden Sie sie in Emp ** Typen umwandeln) und dann eine negative Ganzzahl, Null oder eine positive ganze Zahl zurückgeben, wenn der erste Eintrag kleiner als, gleich oder größer als ist der zweite jeweils.

Bei der totalen Sortierung können Sie einfach die zweite total von der ersten subtrahieren. Wenn die erste Summe kleiner als die zweite ist, ergibt dies eine negative Zahl, und das Gegenteil ist der Fall, wenn die erste Summe größer als die zweite Summe ist. Wenn sie gleich sind, wird Null zurückgegeben.

int compareByTotal(const void *first, const void *second) 
{ 
    int firstTotal = (*(Emp **)first)->total; 
    int secondTotal = (*(Emp **)second)->total; 

    return firstTotal - secondTotal; 
} 

Die zweite, da es sich um ein String-Vergleich ist, den Wert eines strcmp zurückkehren kann (die die gleichen Rückgabewert Konventionen gehorcht):

int compareByName(const void *first, const void *second) 
{ 
    const char *firstName = (*(Emp **)first)->name; 
    const char *secondName = (*(Emp **)second)->name; 

    return strcmp(firstName, secondName); 
} 

Dann können Sie einfach qsort in denen vorbei rufen Funktionsnamen:

/* given: */ 
Emp *nameArray[empSize];//an array of pointers to point to entries alphabetically 
Emp *salesArray[empSize]; //an array of pointers to pointing to entries by sales 

/* use: */ 
qsort(nameArray, empSize, sizeof(*nameArray), &compareByName); 
qsort(salesArray, empSize, sizeof(*salesArray), &compareByTotal); 
1

Ein Beispiel auf Namen für die Sortierung:

#include <stdio.h> 
#include <stdlib.h> 
#define MAX_NAME 20 
#define NUM_MONTHS 12 

typedef struct EMP { 
    char name[MAX_NAME + 1]; 
    int monthSales[NUM_MONTHS]; 
    int total; 
} Emp; 

int compareName(const void * a, const void * b) 
{ 
    return (strcmp(((Emp*)a)->name, ((Emp*)b)->name)); 
} 

int main() 
{ 
    Emp *data; 
    int empSize = 100; 
    qsort(data, empSize, sizeof(Emp), compareName); 
    // qsort(data, empSize, sizeof(Emp), compareSales); 
    return 0; 
} 
+1

Warum verwenden Sie 'sizeof (int)' als drittes Argument für 'qsort()'? –

+1

@PlatinumAzure, 'size: Größe in Bytes jedes Elements im Array' – perreal

+1

Technisch gesehen sind die Elemente 'Emp's (nicht einmal Zeiger auf sie), aber im OP's Beispiel sind sie' Emp *' s . Diese haben nicht die gleiche Größe wie "sizeof (int)", insbesondere auf einem 64-Bit-System. Außerdem ist es viel sicherer, "sizeof (* data)" trotzdem zu verwenden. So ist es generischer und zukunftssicher. –