Pile et listes chaînées
Fermé
Theo_0055
Messages postés
275
Date d'inscription
mardi 21 juillet 2020
Statut
Membre
Dernière intervention
19 janvier 2023
-
1 nov. 2021 à 16:15
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 - 4 nov. 2021 à 12:02
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 - 4 nov. 2021 à 12:02
A voir également:
- Pile et listes chaînées
- Pile carte mere - Guide
- L'accu pile est déchargé nikon coolpix - Forum Nikon
- Impossible de créer une nouvelle page de garde pour la pile - Forum Windows 10
- Taille pile manette wii - Forum Wii
- Triez cette liste par ordre alphabétique des villes et par note de la meilleure à la moins bonne. quel mot est formé par les 8 premières lettres de la colonne code ? ✓ - Forum Excel
9 réponses
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
2 nov. 2021 à 09:36
2 nov. 2021 à 09:36
Bonjour Theo_0055,
Une "pile" peut être implémentée de plusieurs façons en C.
Si tu disposes d'un code que tu as réalisé et qui gère une pile pour un caractère, il est possible que ton code puisse être adapté pour gérer des chaînes de caractères.
Utilises-tu une liste chaînée, un simple tableau, autre chose ?
Dal
Une "pile" peut être implémentée de plusieurs façons en C.
Si tu disposes d'un code que tu as réalisé et qui gère une pile pour un caractère, il est possible que ton code puisse être adapté pour gérer des chaînes de caractères.
Utilises-tu une liste chaînée, un simple tableau, autre chose ?
Dal
Theo_0055
Messages postés
275
Date d'inscription
mardi 21 juillet 2020
Statut
Membre
Dernière intervention
19 janvier 2023
1
2 nov. 2021 à 09:46
2 nov. 2021 à 09:46
J’utilise une liste chaîné et une pile
Les caractères et chaînes de caractère sont dans ma liste chaîné et je veux empiler cela sur ma pile
Les caractères et chaînes de caractère sont dans ma liste chaîné et je veux empiler cela sur ma pile
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
2 nov. 2021 à 11:52
2 nov. 2021 à 11:52
Dans ton code, tu dois donc certainement définir une struct, et avec ce type struct que tu attribues aux maillons de ta liste chaînée, tu dois stocker :
Peux-tu poster ton type struct avec lequel tu gères une pile de char, stp ?
Tu dois aussi avoir des fonctions de manipulation de la pile, qui te permettent d'ajouter un élément, de retirer, retourner le nombre d'éléments de la pile, etc. Mais voyons déjà quelle tête a ton type.
- un moyen d'accéder à l'élément contenu dans le maillon
- un pointeur sur l'élément suivant
Peux-tu poster ton type struct avec lequel tu gères une pile de char, stp ?
Tu dois aussi avoir des fonctions de manipulation de la pile, qui te permettent d'ajouter un élément, de retirer, retourner le nombre d'éléments de la pile, etc. Mais voyons déjà quelle tête a ton type.
Theo_0055
Messages postés
275
Date d'inscription
mardi 21 juillet 2020
Statut
Membre
Dernière intervention
19 janvier 2023
1
2 nov. 2021 à 12:10
2 nov. 2021 à 12:10
typedef struct Element Element; struct Element{ int nombre; Element *suivant; }; typedef struct Pile Pile; struct Pile{ Element *sommet; }; void empiler_char(Pile *pile,char& carac){ Element *nouveau = malloc(sizeof(*nouveau)); if (pile == NULL || nouveau == NULL) exit(EXIT_FAILURE); nouveau->nombre = carac; nouveau->suivant = pile->sommet; pile->sommet = nouveau; }
Theo_0055
Messages postés
275
Date d'inscription
mardi 21 juillet 2020
Statut
Membre
Dernière intervention
19 janvier 2023
1
2 nov. 2021 à 12:11
2 nov. 2021 à 12:11
Maintenant,je veux créer une fonction void empiler_chaineCarac qui empile une chaine de caractere
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Theo_0055
Messages postés
275
Date d'inscription
mardi 21 juillet 2020
Statut
Membre
Dernière intervention
19 janvier 2023
1
2 nov. 2021 à 12:58
2 nov. 2021 à 12:58
J’ai une petite piste esceque on doit faire tant que on a pas fini de parcourir la chaîné de caractère,on ajoute le caractère dans la pile en faisant appel à empiler_char?
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
Modifié le 2 nov. 2021 à 14:03
Modifié le 2 nov. 2021 à 14:03
Salut Theo_0055,
OK, 2 remarques sur ton code avant d'entrer dans le vif du sujet : ton membre nombre est de type int, alors que tu veux y stocker des char ; deuxièmement dans ton prototype
Tu peux rendre ton code plus générique en mettant le type géré dans un typedef.
Ton idée dans ce que tu postes est de stocker la donnée dans le maillon, mais en utilisant directement le type char dans les paramètres de ta fonction. En faisant cela, ton code d'ajout devient spécifique aux données traitées.
Une autre approche serait de rendre ton code plus générique pour que ta pile puisse traiter n'importe quel type de données avec un minimum de changements.
Ce code devrait gérer une pile de char en copiant le char passé en tant que type Donnee dans la pile.
Ensuite, il suffit de changer
Cela fonctionne car, dans
Si tu veux que ta liste gère une copie des données passées, stockée sous la forme de tableau de char dans la pile, alors tu peux le faire aussi, mais il faut ruser car l'opérateur d'affectation
Dans
OK, 2 remarques sur ton code avant d'entrer dans le vif du sujet : ton membre nombre est de type int, alors que tu veux y stocker des char ; deuxièmement dans ton prototype
void empiler_char(Pile *pile,char& carac)la partie
char& caracn'est pas du C (cela ressemble à une référence C++).
Tu peux rendre ton code plus générique en mettant le type géré dans un typedef.
Ton idée dans ce que tu postes est de stocker la donnée dans le maillon, mais en utilisant directement le type char dans les paramètres de ta fonction. En faisant cela, ton code d'ajout devient spécifique aux données traitées.
Une autre approche serait de rendre ton code plus générique pour que ta pile puisse traiter n'importe quel type de données avec un minimum de changements.
typedef char Donnee; typedef struct Element Element; struct Element{ Donnee donnee; Element *suivant; }; void empiler_donnee(Pile *pile, Donnee donnee){ if (pile == NULL) exit(EXIT_FAILURE); Element *nouveau = malloc(sizeof(*nouveau)); if (nouveau == NULL) exit(EXIT_FAILURE); nouveau->donnee = donnee; nouveau->suivant = pile->sommet; pile->sommet = nouveau; }
Ce code devrait gérer une pile de char en copiant le char passé en tant que type Donnee dans la pile.
Ensuite, il suffit de changer
typedef char Donnee;en
typedef char * Donnee;pour gérer une liste de pointeurs sur char où tu stockes des pointeurs sur char passés à la fonction empiler_donnees().
Cela fonctionne car, dans
empiler_donnee, l'opérateur d'affectation dans
nouveau->donnee = donnee;va simplement affecter un pointeur.
Si tu veux que ta liste gère une copie des données passées, stockée sous la forme de tableau de char dans la pile, alors tu peux le faire aussi, mais il faut ruser car l'opérateur d'affectation
=ne permet pas l'affectation de types tableaux en langage C. En revanche, il peut gérer les struct. Donc, en rusant, tu peux réutiliser le même code en changeant ton type Donnee comme ceci :
#define MAX_LEN 500 typedef struct Donnee Donnee; struct Donnee { char str[MAX_LEN]; };
Dans
empiler_donnee(), l'opérateur d'affectation à la ligne
nouveau->donnee = donnee;va alors copier le contenu de la struct (en faisant une opération équivalente à un memcpy()).
Theo_0055
Messages postés
275
Date d'inscription
mardi 21 juillet 2020
Statut
Membre
Dernière intervention
19 janvier 2023
1
2 nov. 2021 à 13:31
2 nov. 2021 à 13:31
1.Pour le char& carac en fait c’était une erreur de frappe c’était char carac tout court sans &
2.Si j’ai bien compris
typedef char Donnee donnee =définition du type Donnee (qui est un char)
3.votre dernier Donnee il est censé gérer les chaînes de caractères c’est ça?
4.J’ai essayé plusieurs fois d’écrire un code pour gérer n’importe quel type de Donnee (char,int,double,..) mais le problème je sais pas comment m’y prendre
Car créer à chaque fois une fonction qui dépile int,une autre des char.. c’est un peu répétitif et j’aimerais créer une seule qui gère tous les types
2.Si j’ai bien compris
typedef char Donnee donnee =définition du type Donnee (qui est un char)
3.votre dernier Donnee il est censé gérer les chaînes de caractères c’est ça?
4.J’ai essayé plusieurs fois d’écrire un code pour gérer n’importe quel type de Donnee (char,int,double,..) mais le problème je sais pas comment m’y prendre
Car créer à chaque fois une fonction qui dépile int,une autre des char.. c’est un peu répétitif et j’aimerais créer une seule qui gère tous les types
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
2 nov. 2021 à 13:54
2 nov. 2021 à 13:54
2.Si j’ai bien compris
typedef char Donnee donnee =définition du type Donnee (qui est un char)
oui
3.votre dernier Donnee il est censé gérer les chaînes de caractères c’est ça?
J'en au proposé deux qui sont susceptibles permettre au code gérant la liste de gérer des chaînes de caractères. Le dernier est l'un d'eux.
4.J’ai essayé plusieurs fois d’écrire un code pour gérer n’importe quel type de Donnee (char,int,double,..) mais le problème je sais pas comment m’y prendre
Car créer à chaque fois une fonction qui dépile int,une autre des char.. c’est un peu répétitif et j’aimerais créer une seule qui gère tous les types
Je viens de t'indiquer une façon de faire, le seul changement à faire étant sur le typedef qui définit le type de tes données.
typedef char Donnee donnee =définition du type Donnee (qui est un char)
oui
3.votre dernier Donnee il est censé gérer les chaînes de caractères c’est ça?
J'en au proposé deux qui sont susceptibles permettre au code gérant la liste de gérer des chaînes de caractères. Le dernier est l'un d'eux.
4.J’ai essayé plusieurs fois d’écrire un code pour gérer n’importe quel type de Donnee (char,int,double,..) mais le problème je sais pas comment m’y prendre
Car créer à chaque fois une fonction qui dépile int,une autre des char.. c’est un peu répétitif et j’aimerais créer une seule qui gère tous les types
Je viens de t'indiquer une façon de faire, le seul changement à faire étant sur le typedef qui définit le type de tes données.
Theo_0055
Messages postés
275
Date d'inscription
mardi 21 juillet 2020
Statut
Membre
Dernière intervention
19 janvier 2023
1
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
2 nov. 2021 à 14:03
2 nov. 2021 à 14:03
Par exemple si je met
Ça peut générer des char et des int en même temp
Par exemple si empile_donnee ,on lui donne un int en 2 eme paramètre ça va marcher,de même que pour char?
typedef char Donnee typedef int Donnee
Ça peut générer des char et des int en même temp
Par exemple si empile_donnee ,on lui donne un int en 2 eme paramètre ça va marcher,de même que pour char?
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
>
Theo_0055
Messages postés
275
Date d'inscription
mardi 21 juillet 2020
Statut
Membre
Dernière intervention
19 janvier 2023
Modifié le 2 nov. 2021 à 14:46
Modifié le 2 nov. 2021 à 14:46
Tu ne peux pas écrire cela, car cela revient à tenter de redéfinir un alias de type. Ma suggestion d'une modification minimale de ton code pour gérer un autre type de données que le char était que tu définisses ton alias de type Donnee avec le type de données que tu veux gérer dans ta pile. Ton code générique gérera ce type de données.
Maintenant tu sembles avoir un besoin différent. Si dans chaque maillon tu veux stocker un char et un int, tu peux créer un type Donnee qui soit une struct avec ces deux membres. Si dans chaque maillon tu veux stocker un char ou un int, tu peux créer une struct qui contient une union dans l'un de ses membres avec ces deux types et l'autre membre qui stocke le type (la façon courante de le faire est avec un enum).
Une autre façon de rendre ta pile générique est de stocker des
Maintenant tu sembles avoir un besoin différent. Si dans chaque maillon tu veux stocker un char et un int, tu peux créer un type Donnee qui soit une struct avec ces deux membres. Si dans chaque maillon tu veux stocker un char ou un int, tu peux créer une struct qui contient une union dans l'un de ses membres avec ces deux types et l'autre membre qui stocke le type (la façon courante de le faire est avec un enum).
Une autre façon de rendre ta pile générique est de stocker des
void *dans ta pile et laisser le soin aux fonctions appelantes de passer le pointeur void et le transtyper lorsqu'il est récupéré. Tu avais posté un message où tu posais des questions sur les
void *et qui a été supprimé (auquel j'avais répondu... ce qui fait que ma réponse a aussi été supprimée...). Cependant, tu ne pourras pas mélanger les types dans un même programme, à moins de stocker aussi dans une struct l'indication du type, car sinon la fonction appelante ne saura pas comment exploiter le pointeur.
Theo_0055
Messages postés
275
Date d'inscription
mardi 21 juillet 2020
Statut
Membre
Dernière intervention
19 janvier 2023
1
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
2 nov. 2021 à 16:37
2 nov. 2021 à 16:37
Ah bon vous m’avez répondu,pourtant j’ai rien vu.je pensais que ma réponse a été ignoré d’où ma suppression
Theo_0055
Messages postés
275
Date d'inscription
mardi 21 juillet 2020
Statut
Membre
Dernière intervention
19 janvier 2023
1
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
2 nov. 2021 à 16:44
2 nov. 2021 à 16:44
Par exemple ,esce qu’on peut écrire
Et on met
Le void * va pointer sur n’importe quel type de donnée
Bon après vous avez dit que ça peut causer problème si le type n’est pas indiqué
Comment retranstyper?
Le void * ,m’a question est plus une question de curiosité qu’autre chose car en classe on l’a jamais utilisé
typedef void * Donnee; typedef struct Element Element; struct Element{ Donnee donnee; Element *suivant;
Et on met
void empiler_donnee(Pile *pile, Donnee donnee){
Le void * va pointer sur n’importe quel type de donnée
Bon après vous avez dit que ça peut causer problème si le type n’est pas indiqué
Comment retranstyper?
Le void * ,m’a question est plus une question de curiosité qu’autre chose car en classe on l’a jamais utilisé
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
Modifié le 2 nov. 2021 à 16:31
Modifié le 2 nov. 2021 à 16:31
Voilà une illustration d'une struct comprenant une union et un membre permettant de conserver le type de la donnée, en utilisant un enum pour codifier les types.
Lorsque tu dépiles, tu consultes d'abord le type récupéré, et, en fonction du type, tu accèdes à la valeur récupérée à travers l'union récupérée.
Dal
#include <stdlib.h> enum type_donnee { CHAR, INT, DOUBLE, PCHAR, MAX_TYPES }; union val { char c; int i; double d; char * s; }; typedef struct Donnee Donnee; struct Donnee { union val val; enum type_donnee type; }; typedef struct Element Element; struct Element{ Donnee donnee; Element *suivant; }; typedef struct Pile Pile; struct Pile{ Element *sommet; }; Pile * init_pile(void) { Pile * p = malloc(sizeof(*p)); p->sommet = NULL; return p; } void empiler_donnee(Pile *pile, Donnee donnee){ if (pile == NULL) exit(EXIT_FAILURE); Element *nouveau = malloc(sizeof(*nouveau)); if (nouveau == NULL) exit(EXIT_FAILURE); nouveau->donnee = donnee; nouveau->suivant = pile->sommet; pile->sommet = nouveau; } int main(void) { Pile * p = init_pile(); Donnee donnee; donnee.val.c = 'A'; donnee.type = CHAR; empiler_donnee(p, donnee); donnee.val.i = 123; donnee.type = INT; empiler_donnee(p, donnee); donnee.val.d = 123.45; donnee.type = DOUBLE; empiler_donnee(p, donnee); donnee.val.s = "saperlipopette"; donnee.type = PCHAR; empiler_donnee(p, donnee); return 0; }
Lorsque tu dépiles, tu consultes d'abord le type récupéré, et, en fonction du type, tu accèdes à la valeur récupérée à travers l'union récupérée.
Dal
Theo_0055
Messages postés
275
Date d'inscription
mardi 21 juillet 2020
Statut
Membre
Dernière intervention
19 janvier 2023
1
Modifié le 2 nov. 2021 à 17:07
Modifié le 2 nov. 2021 à 17:07
Merci j’ai compris c’est plus clair là.
Je vais essayer de finir mon projet d'informatique et j'espère réussir a le finir sans demander de l'aide.
Je vais essayer de finir mon projet d'informatique et j'espère réussir a le finir sans demander de l'aide.
Theo_0055
Messages postés
275
Date d'inscription
mardi 21 juillet 2020
Statut
Membre
Dernière intervention
19 janvier 2023
1
2 nov. 2021 à 17:17
2 nov. 2021 à 17:17
Je voulais aussi savoir esceque on pouvait se passer du enum type_Donnee car pour moi union val gère déjà bien les type pour ma part
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
>
Theo_0055
Messages postés
275
Date d'inscription
mardi 21 juillet 2020
Statut
Membre
Dernière intervention
19 janvier 2023
Modifié le 2 nov. 2021 à 17:36
Modifié le 2 nov. 2021 à 17:36
Si tu ne gardes pas trace du type, lorsque tu dépiles, tu ne sais pas comment accéder aux données stockées dans l'union pour qu'elle soient interprétées selon le bon type.
Comme je le disais :
Lorsque tu dépiles, tu consultes d'abord le type récupéré, et, en fonction du type, tu accèdes à la valeur récupérée à travers l'union récupérée.
Comme je le disais :
Lorsque tu dépiles, tu consultes d'abord le type récupéré, et, en fonction du type, tu accèdes à la valeur récupérée à travers l'union récupérée.
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
2 nov. 2021 à 18:09
2 nov. 2021 à 18:09
Considère le code suivant :
Comment vais-je l'exploiter ?
Il me faut stocker le type pour garder cette information.
Si le type que je stocke correspond à l'enum PCHAR et que, par convention, PCHAR désigne un pointeur sur char permettant d'accéder à une chaîne C, alors, je pourrais écrire ceci :
/* je mets à zéro la struct, car je vais faire des trucs funky */ Donnee donnee = { 0 }; char str[] = "saperlipopette"; donnee.val.s = str; /* maintenant, disons que je récupère donnee de la Pile sans * information sur le type, tous ces printf sont du C "valide" * mais un seul restitue correctement l'information stockée */ printf("donnee est-elle une chaîne %s\n", donnee.val.s); printf("donnee est-elle un char %c\n", donnee.val.c); printf("donnee est-elle un entier %d\n", donnee.val.i); printf("donnee est-elle un double %f\n", donnee.val.d);
Comment vais-je l'exploiter ?
Il me faut stocker le type pour garder cette information.
Si le type que je stocke correspond à l'enum PCHAR et que, par convention, PCHAR désigne un pointeur sur char permettant d'accéder à une chaîne C, alors, je pourrais écrire ceci :
Donnee donnee; char str[] = "saperlipopette"; donnee.val.s = str; donnee.type = PCHAR; /* maintenant, disons que je récupère donnee de la Pile avec * information sur le type. Je vais pouvoir déterminer comment * adapter mon printf selon le cas */ switch (donnee.type) { case PCHAR: printf("donnee est une chaîne %s\n", donnee.val.s); break; case CHAR: printf("donnee est un char %c\n", donnee.val.c); break; case INT: printf("donnee est un entier %d\n", donnee.val.i); break; case DOUBLE: printf("donnee est un double %f\n", donnee.val.d); break; default: printf("Erreur : type non géré\n"); }
Theo_0055
Messages postés
275
Date d'inscription
mardi 21 juillet 2020
Statut
Membre
Dernière intervention
19 janvier 2023
1
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
2 nov. 2021 à 18:21
2 nov. 2021 à 18:21
Ok tout est clair désormais dans ma tête
Je voulais aussi savoir si j’ai une fonction
Le int avec ce que vous m’avez expliqué on peut le remplacer par
Je voulais aussi savoir si j’ai une fonction
int depiler (Pile * p)
Le int avec ce que vous m’avez expliqué on peut le remplacer par
Donnee depiler (Pile * p)
Theo_0055
Messages postés
275
Date d'inscription
mardi 21 juillet 2020
Statut
Membre
Dernière intervention
19 janvier 2023
1
2 nov. 2021 à 16:34
2 nov. 2021 à 16:34
Merci je vais essayer de comprendre et je vous refait signe