Bonjour,
Je continue mes études concernant le langage C et en particulier la partie allocation dynamique de mémoire.
J’ai été faire un tour sur openclassrooms.com afin d’essayer de comprendre les listes chaînées ou liste liées. J’ai parfaitement compris sur le fond comment elles fonctionnaient (du moins c'est ce que je pense), il s’agit tout simplement de structures qui sont reliées entre elles par des pointeurs. Pourquoi par des pointeurs ? Parce que contrairement aux tableaux qui sont mémorisés dans un bloc de mémoire contigüe, les structures peuvent être stockées à des endroits différents dans la mémoire (ce qui présente un confort non négligeable notamment en matière de flexibilité), les pointeurs permettent de situer les structures, de les liées afin de mieux les retrouver. Le dernier élément de la liste pointera vers un pointeur NULL.
J’ai repris en partie le code d’exemple ici sans la suppression d’un élément qui ne pose pas de problème de compréhension :
https://openclassrooms.com/fr/courses/19980-apprenez-a-programmer-en-c/19733-stockez-les-donnees-avec-les-listes-chainees
Sur la forme j’ai compris ce code mais j’ai du l’adapter au niveau de l’allocation dynamique de la mémoire pour les structures :
Dans la fonction initialisation()
au lieu de :
Liste *liste = malloc(sizeof(*liste));
Element *element = malloc(sizeof(*element));
Lire :
Liste *liste; // pointeur vers la structure Liste
Element *element; // pointeur vers la structure Element
liste = (Liste*)malloc(sizeof(*liste));
element = (Element*)malloc(sizeof(*element));
Dans la fonction insertion () au lieu de :
Element *nouveau = malloc(sizeof(*nouveau));
Lire :
Element *nouveau; // pointeur vers un nouvel "Element"
nouveau = (Element*)malloc(sizeof(*nouveau)); // allocation dynamique de la mémoire
Les structures étant des variables comme les autres, il faut donc caster le résultat du malloc() comme le C++ l’impose (le programme étant écrit en C).
J’ai ajouté la gestion d’un tableau de char, j’ai créé trois structures.
Avant d’aller plus loin avec les listes doublements chaînées, je souhaitais vous soumettre la manière dont j’avais compris la gestion de ces variables. Peut-être que quelque chose m’échappe ?
Voici ma version du code testé sur UNO :
typedef struct Element Element; // Element devient équivalent à struct Element
typedef struct Liste Liste; // Liste devient équivalent à struct Liste
struct Element
{
char nom[10] ;
int nombre;
Element *suivant; // pointeur qui va permettre la liaison entre les éléments de la liste
};
struct Liste //contient l'adresse du premier élément de la liste dans premier
{
Element *premier;
};
void setup() {
Serial.begin(115200);
Liste *maListe = initialisation();
insertion(maListe, "Bonsoir", 25);
insertion(maListe, "coucou", 6);
afficherListe(maListe);
}
void loop() {}
Liste *initialisation() //crée la struture de contrôle et le premier élément de la liste
{
Liste *liste; // pointeur vers la structure Liste
Element *element; // pointeur vers la structure Element
liste = (Liste*)malloc(sizeof(*liste));
element = (Element*)malloc(sizeof(*element));
if (liste == NULL || element == NULL)
{
exit(EXIT_FAILURE);
}
strcpy (element->nom , "bonjour");
element->nombre = 10;
element->suivant = NULL;
liste->premier = element;
return liste;
}
void insertion(Liste *liste, const char *nvNom, int nvNombre)
{
/* Création du nouvel élément */
Element *nouveau; // pointeur vers un nouvel "Element"
nouveau = (Element*)malloc(sizeof(*nouveau)); // allocation dynamique de la mémoire
if (liste == NULL || nouveau == NULL)
{
exit(EXIT_FAILURE);
}
nouveau->nombre = nvNombre; // affectation pour int
strcpy (nouveau->nom , nvNom); // affectation pour le tableau de caractères
/* Insertion de l'élément au début de la liste */
nouveau->suivant = liste->premier; /* Insertion en début de liste, du coup le pointeur suivant prend l'adresse de premier
Le nouvel élément pointe vers son futur successeur qui est l'actuel premier élément de la liste */
liste->premier = nouveau; // premier pointe logiquement vers nouveau
}
void afficherListe(Liste *liste)
{
if (liste == NULL)
{
exit(EXIT_FAILURE);
}
Element *actuel = liste->premier;
while (actuel != NULL) // tant qu'on arrive pas au bout de la liste
{
Serial.println(actuel->nom);
Serial.println(actuel->nombre);
actuel = actuel->suivant;
}
}
Bonne journée.
Edité une fois