2014-05-07 5 views
1

Je charge des données dans struct.Sauvegarde des pointeurs de struct c

struct test { 
    char x[101]; 
    char y[101];  
    int z; 
}; 

Puis-je créer la mémoire pour struct

struct test * data; 
data = malloc(10 * sizeof(struct test)); 

et remplir les données comme celui-ci

data[0].z = 123; 

Cela fonctionne bien. Mais je veux trier ces structures. Comme les trier en fonction de l'attribut z.

Mon idée était de créer un nouveau tableau et de le remplir avec des pointeurs qui pointent vers la bonne structure.

Quelqu'un peut-il me dire comment ou s'il y a un meilleur moyen?

Merci

+1

La façon dont vous avez mentionné la création d'un nouveau tableau de pointeurs est la meilleure, c'est-à-dire qu'il n'est pas nécessaire de trier les données réelles. –

+2

Vous pouvez également utiliser 'qsort' pour trier' data'. –

+0

Ouais @FiddlingBits mais je ne sais pas comment le faire – user2976389

Répondre

0

Une façon de procéder est d'utiliser qsort, l'algorithme de tri général fourni dans la bibliothèque standard pour trier des séquences de données définies par l'utilisateur. Dans le but de faire ce qui suit:

  • les données source doivent rester non touchées.
  • le « sorted » l'accès doit être fourni par une liste de pointeurs vers les données intactes en haut

c'est une façon de le faire en utilisant la fonction de bibliothèque standard qsort():

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <time.h> 

struct test { 
    char x[101]; 
    char y[101]; 
    int z; 
}; 

int cmp_test_ptrs(const void* arg1, const void* arg2) 
{ 
    struct test const * lhs = *(struct test const * const*)arg1; 
    struct test const * rhs = *(struct test const * const*)arg2; 
    return (lhs->z < rhs->z) ? -1 : (rhs->z < lhs->z); 
} 

int main() 
{ 
    srand((unsigned int)time(0)); 

    // populate data array. 
    struct test * data = malloc(10 * sizeof(*data)); 
    for (int i=0; i<10; ++i) 
    { 
     data[i].z = rand() % 20; 
     printf("%d ", data[i].z); 
    } 
    printf("\n"); 

    // allocate a pointer array to use as a sort-bed, copying each 
    // structure address into this pointer array afterward 
    struct test **ptrs = malloc(10 * sizeof(*ptrs)); 
    for (int i=0; i<10; ++i) 
     ptrs[i] = data+i; 

    // sort the pointer bed using our comparator 
    qsort(ptrs, 10, sizeof(*ptrs), cmp_test_ptrs); 

    // ptrs now has sorted pointers. Note the dereference for access 
    // to the actual data, which remains where it originally was. 
    for (int i=0; i<10; ++i) 
     printf("%d ", ptrs[i]->z); 
    printf("\n"); 

    free(ptrs); 
    free(data); 
    return 0; 
} 

Exemple de sortie

11 7 6 17 8 8 11 4 7 5 
4 5 6 7 7 8 8 11 11 17 

Important à noter est la structu originale re array est resté intact. Nous avons trié une séquence de pointeurs, pas les structures elles-mêmes, et utilisé ce que ces pointeurs pointaient vers comme critères pour le tri.

En tout cas, j'espère que ça aide.Étudiez le comparateur et la configuration pour qsort() attentivement. Ils sont importants. Vous pouvez en savoir plus sur qsort() here.

2

Cela dépend de votre objectif. Si vous essayez de comprendre ce qui serait le plus efficace pour les programmeurs, alors la création d'un foncteur de classement basé sur l'attribut z de votre struct, et le tri de la liste directement, est plus facile. Cependant, si vous êtes concerné par l'efficacité du programme, il sera plus rapide de trier les pointeurs, comme suggéré par Fiddling Bits. Cependant, vous devez garder à l'esprit que cela vous donnera une liste triée de pointeurs - votre tableau de données sera toujours dans le même ordre.

Par exemple, si datapoints est votre tableau de pointeurs, et que vous vouliez trier par la valeur de z, vous pouvez définir la comparaison

int compare(const void *a, const void *b) 
{ 
    return ((*(test *)a).z -(*(test *)b).z); 
} 

Et puis appelez

qsort(datapoints, 10, sizeof(test), compare); 

Documentation complète pour qsort peut être trouvé here:

+0

bien avec moi.pouvez-vous montrer comment le faire – user2976389

+2

@ user2976389 Commencez à travailler dessus, postez une nouvelle question si vous êtes coincé quelque part. Si vous voulez que quelqu'un écrive du code pour vous, vous êtes sur le mauvais site. –

+0

@RedAlert Ralentissez, je n'ai pas demandé de code de tri complet, je viens de demander comment puis-je faire tableau de pointeur – user2976389

0

Ou vous pouvez simplement les trier dans le même tableau et probablement enregistrer de la mémoire (4 octets pour un pointeur de tout type): P Peu importe vraiment, les pointeurs fonctionneront bien je suppose. Mais je pense que dans certains cas, les pointeurs seront plus utiles que si vous le triez dans le tableau, vous aurez besoin d'une structure temporaire définie pour contenir les structures quand vous triez et si vous êtes struct que vous aurez effectivement prendre beaucoup plus de mémoire que 4 octets. + Souvenez-vous également que lorsque vous définissez un pointeur sur une structure, accédez-y avec l'opérateur ->. Utilisation: STRUCT_POINTER_NAME->VARIABLE

Questions connexes