IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Listes chaînées génériques


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 104
    Par défaut [Résolu] Listes chaînées génériques
    Bonsoir,

    J'ai un projet d'informatique qui utilise beaucoup de listes chaînées, donc pour éviter de recoder à chaque fois les fonctions qui relient les maillons entre eux, j'ai pensé à utiliser des listes chaînées génériques.

    Mais à partir de là je me rends compte que ça nécessite quand même beaucoup de fonctions à coder à côté pour gérer les données qui elles ne sont pas génériques... D'où une première question est-ce vraiment utile/utilisé ?

    J'ai quand même codé une bibliothèque de fonctions gérant tout ça, mais lorsque dans le champ void* data, je souhaite insérer une structure Point, seul le premier champ x garde sa valeur, les deux autres étant mis à 0. Je ne comprends pas pourquoi :-S.

    Voici mon code :

    bibilothèque : listes génériques
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #include "d_linked_list.h"
     
    Item*
    create_item(void* data, size_t size)
    {
        Item* new_item = NULL;
     
        if ((new_item = malloc(sizeof(Item))))
        {
    	if ((new_item->data = malloc(size)))
    	{
    	    memcpy(new_item->data, data, size);
    	    new_item->next = NULL;
    	    new_item->previous = NULL;
    	}
    	else
    	{
    	    fprintf(stderr, "Allocation impossible\n");
    	}
        }
        else
        {
    	fprintf(stderr, "Allocation impossible\n");
        }
     
        return new_item;
    }
     
    List
    add_item_top_list(List* list, void* data, size_t size)
    {
        Item* item = NULL;
     
        if ((item = create_item(data, size)))
        {
    	if (*list != NULL)
    	{
    	    item->next = *list;
    	    item->next->previous = item;
    	}
    	*list = item;
        }
        else
        {
    	return NULL;
        }
     
        return *list;
    }
     
    List
    add_item_end_list(List* list, void* data, size_t size)
    {
        Item* item = NULL;
        Item* index = NULL;
     
        if ((item = create_item(data, size)))
        {
    	if (*list == NULL)
    	{
    	    *list = item;
    	}
    	else
    	{
    	    index = go_to_end_list(list);
    	    index->next = item;
    	    item->previous = index;
    	}
        }
        else
        {
    	return NULL;
        }
     
        return *list;
    }
     
    Item*
    go_to_end_list(List* list)
    {
        Item* index = *list;
     
        while (index->next != NULL)
        {
    	index = index->next;
        }
     
        return index;
    }
     
    void
    extract_item(List* list, Item* item)
    {
        if (*list == item)
        {
    	*list = item->next;
    	item->next->previous = NULL;
    	item->next = NULL;
        }
        else if (item->next == NULL)
        {
    	item->previous->next = NULL;
    	item->previous = NULL;
        }
        else
        {
    	item->previous->next = item->next;
    	item->next->previous = item->previous;
    	item->next = NULL;
    	item->previous = NULL;
        }
    }
     
    void
    destroy_item(Item* item)
    {
        free(item);
    }
     
    void
    destroy_list(List* list)
    {
        Item* tmp = *list;
     
        do
        {
    	tmp = tmp->next;	
    	free(tmp->previous);
        } while (tmp != NULL);
    }
     
    int
    number_of_items(List* list)
    {
        int n = 0;
        Item* item = NULL;
     
        item = *list;
        while (item != NULL)
        {
    	n++;
    	item = item->next;
        }
     
        return n;
    }
     
    Item*
    get_last_item(List* list)
    {
        Item* item = NULL;
     
        item = *list;
        while (item->next != NULL)
        {
    	item = item->next;
        }
     
        return item;
    }
    header de la biblio :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #ifndef D_LINKED_LIST
    #define D_LINKED_LIST
     
    typedef struct item
    {
        void* data;
        struct item* next;
        struct item* previous;
    } Item, *List;
     
    Item*
    create_item(void* data, size_t size);
     
    List
    add_item_top_list(List* list, void* data, size_t size);
     
    List
    add_item_end_list(List* list, void* data, size_t size);
     
    Item*
    go_to_end_list(List* list);
     
    void
    destroy_item(Item* item);
     
    void
    destroy_list(List* list);
     
    int
    number_of_items(List* list);
     
    Item*
    get_last_item(List* list);
     
    #endif
    Le fichier de test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    #include <stdio.h>
    #include <stdlib.h>
     
    #include "a_star.h"
    #include "d_linked_list.h"
     
    Point*
    creer_point(int x, int y, int distance)
    {
        Point* nv_point = NULL;
     
        if ((nv_point = malloc(sizeof(Point))))
        {
    	nv_point->x = x;
    	nv_point->y = y;
    	nv_point->distance = distance;
        }
        else
        {
    	fprintf(stderr, "Allocation impossible\n");
        }
     
        return nv_point;
    }
     
    void
    afficher_liste(List* list)
    {
        Item* item = NULL;
        Point* point = NULL;
     
        item = *list;
        while (item != NULL)
        {
    	point = (Point*) item->data;
    	printf("%d %d %d\n", point->x, point->y, point->distance);
    	item = item->next;
        }
    }
     
    int
    main(void)
    {
        List list = NULL;
        int i = 0;
        Point* point = NULL;
     
        for (i = 0; i < 10; i++)
        {
    	point = creer_point(i, i, i);
    	printf("%d %d %d\n", point->x, point->y, point->distance);
    	list = add_item_end_list(&list, point, sizeof(point));
        }
        afficher_liste(&list);
     
        return 0;
    }
    header du fichier test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #ifndef A_STAR_H
    #define A_STAR_H
     
    #define X 60
    #define Y 40
     
    typedef struct point
    {
        int x;
        int y;
        int distance;
    } Point;
     
    Point*
    creer_point(int x, int y, int distance);
     
    #endif
    On voit apparaître le nom a_star pour l'algorithme de pathfinding, qui sera une des utilisations de la bibilothèque. Donc là j'essaye d'insérer des valeur de 0 à 9 dans les trois champs, on voit bien que la structure point est bien créée. En revanche après l'ajout dans la liste, problème...

    Exemple : au début 111, 222, 333 puis après ajout 100 200 300...

    Sinon, j'ai aussi essayé de faire une structure coordonnées pour rassemble les int x, int y mais ça commençait à faire struct de struct de struct et parfois je me retrouvais avec des item->data->coordonnees.x ou des choses dans la même style sans trop savoir pourquoi...

    Si vous pouviez m'éclairer ce serait sympa ;-).

    Merci à vous.

    Bye.

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 127
    Billets dans le blog
    149
    Par défaut
    Je ne veux pas répondre à ta question ... excuse moi. ( Au moins il y a pas de fausse joie )

    Et tu obligé d'utiliser le C.
    Car dans le C++ il y a un truc qui s'apelle "template" et qui permet de faire des listes ( et autre fonctions en fait ) qui prenne juste un argument, et que celui ci peut s'avéré être ce que tu veux ( comme type ).

    Enfin c'est ce que je comprenais avec le titre du topic , que tu voulais avoir quelque chose capable de prendre en arguments n'importe qu'elle type.

    Après de mémoire , l'utilisation du void* est ultra dangereuse....

    Petit conseil ( j'ai beaucoup de mal à comprendre ton code ... l'heure n'arrange pas trop les choses ) : Commence par faire ta liste , mais en prenant que un type basique ( enfin un float , un int , ou n'importe quoi d'autre ) Juste pour commencer simple , et pour être sur que t'es fonction fasse bien ce que tu veux.
    C'est juste que le coup d'avoir un tableau data de void* ( enfin , oui je crois que c'est ça ) dans la structure même de l'Item complique beaucoup de chose.
    Je pense avoir moyennement compris ce que tu veux faire avec le void* mais c'est très incertain , il me semble. ( Pas dans l'idée , mais dans le comprotement du programme avec les void* )
    Car si tu fais un sizeof de void* il te renvoie 4 ( pour 4bytes ) alors que si tu veux stocker juste un char il ne devrait que te renvoyer 1 ... mais comme il ne sais pas/plus que c'est un char, il renverra 4....
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 104
    Par défaut
    Re,

    Alors après encore quelques tests, j'ai finalement réussi à faire ce que je voulais... Voilà le morceau de code qui fonctionne avec la bibliothèque de mon premier post ;-).

    Merci à toi.

    En revanche si quelqu'un savait si oui ou non l'usage de void* est proscrit ou peu recommandé ? Car bon vu qu'il n'y a que le programmeur qui rentre en contact avec, on est censé savoir ce qu'il y a dedans ?

    Merci à vous.

    Bye.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    #include <stdio.h>
    #include <stdlib.h>
     
    #include "d_linked_list.h"
     
    typedef struct coordonnees
    {
        int x;
        int y;
    } Coordonnees;
     
    typedef struct point
    {
        Coordonnees* coor;
        char* string;
        int distance;
    } Point;
     
    Point*
    creer_point(int x, int y, int distance)
    {
        Point* nv_point = NULL;
     
        if ((nv_point = malloc(sizeof(Point))))
        {
    	if ((nv_point->coor = malloc(sizeof(Coordonnees))))
    	{
    	    if ((nv_point->string = malloc(sizeof(20))))
    	    {
    		nv_point->coor->x = x;
    		nv_point->coor->y = y;
    		sprintf(nv_point->string, "bonjour");
    		nv_point->distance = distance;
    	    }
    	}
    	else
    	{
    	    fprintf(stderr, "Allocation impossible\n");
    	}
        }
        else
        {
    	fprintf(stderr, "Allocation impossible\n");
        }
     
        return nv_point;
    }
     
    void
    print_list(List* list)
    {
        Item* item = NULL;
        Point* point = NULL;
     
        item = *list;
     
        while (item != NULL)
        {
    	point = (Point*) item->data;	
    	printf("%d %d %s %d\n", 
    	       point->coor->x, point->coor->y,point->string,
    	       point->distance);
    	item = item->next;
        }
        printf("\n");
    }
     
    int
    main(void)
    {
        List list = NULL;
        Point* point = NULL;
        int i = 0;
     
     
        for (i = 0; i < 10; i++)
        {
    	point = creer_point(i, i, i);
    	printf("%d %d %d\n", point->coor->x, point->coor->y,
    	       point->distance);
    	add_item_top_list(&list, point, sizeof(Point));
        }
        print_list(&list);
     
        return 0;
    }

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 127
    Billets dans le blog
    149
    Par défaut
    Car bon vu qu'il n'y a que le programmeur qui rentre en contact avec, on est censé savoir ce qu'il y a dedans ?
    Et si tu partage ton programme ... ou que ta liste chainée devient une partie d'un programme développer par plusieur personne ...

    Enfin bref , je sais que l'on se dit que bon , y a pas trop de possibilité que cela arrive.
    Le void* est dangereux si je me rapelle bien ,car le compilo ne peut pas vérifier ce que tu fais. Tu lui dis juste je te passe un pointeur ... après il sait pas trop. Donc y a plein de warning qu'il ne pourra pas te mettre.
    ( Si je me rapelle bien , mais je veux bien que quelqu'un passe , pour me contre dire , ou pas )
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  5. #5
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Le void * c'est à peu près la seule façon de faire des fonctions génériques en C.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 104
    Par défaut
    Re,

    Ok merci pour vos réponses. Sachant que le projet restera dans mes documents je continue sur cette voie .

    Bye

Discussions similaires

  1. Réponses: 10
    Dernier message: 16/11/2010, 09h26
  2. Réponses: 11
    Dernier message: 21/03/2008, 22h46
  3. Réponses: 6
    Dernier message: 14/02/2008, 13h16
  4. Pointeur générique et liste chaînée
    Par jro-daemon dans le forum C
    Réponses: 9
    Dernier message: 23/02/2007, 14h06
  5. Insertion d'un noeud dans une liste chaînée
    Par habib106 dans le forum Assembleur
    Réponses: 8
    Dernier message: 07/04/2004, 22h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo