Pile en C
Fermé
AviateurRex
-
1 oct. 2021 à 01:01
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 - 11 oct. 2021 à 14:51
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 - 11 oct. 2021 à 14:51
Bonjour à tous,
J'ai quelque modifications à apporter à un scripte mais je n'y arrive pas. Le but de mon projet est de créer une pile en C au format LIFO ( last in first out ) consistant donc a ajouter / supprimer des éléments, le seul élément avec lequel on peut interagir étant celui se trouvant au sommet de la pile.
J'ai donc les scripts suivants:
[code]//
// Fichier main.c
//
#include "pile.h"
int main(){
Pile p; Element *elem;
int estSommet=0;
p=pileVide();
pileAjouter(p,1);
pileAjouter(p,2);
pileAjouter(p,3);
while(pileLongueur(p)>0){
if(estSommet == 0){
printf("\nLe sommet de la pile est %0.2f\n\n",*pileSommet(p));
estSommet=1;
}
printf("| %0.2f |\n", *pileSommet(p));
printf("------------\n");
pileSupprimer(p);
}
return (0);
}
[/code]
J'obtient donc avec ce code :
Ce qui est correcte. Maintenant il faudrait que je remplace les élements 1,2,3 de ma pile par : (‘’fonction#1’’, 0x7F543210, ‘’Ok’’) a la place du 1, (fonction#2’’, 0x7F543220, ‘’987654’’) a la place du 2 et (‘’fonction#3’’, 0x7F543230, ‘’123456’’) a la place du 3. Mon code ne compilant que des éléments de type float j'ai essayé de convertir chaque ligne de type str en float avec la fonction strtof() mais celle ci ne converti que les nombres englobé dans dans "".
J'ai pensé a modifier la structure de l'élément de la façon suivante :
Mais toujours rien.
Je dois donc avoir au final l'ordre d'execution suivant:
pileAjouter (‘’fonction#1’’, 0x7F543210, ‘’Ok’’) ;
pileAjouter (‘’fonction#2’’, 0x7F543220, ‘’987654’’) ;
pileAjouter (’fonction#3’’, 0x7F543230, ‘’123456’’) ;
pilelongueur (Pile) ;
pileafficher (Pile) ;
pileSupprimer (Pile) ;
pilelongueur(Pile) ;
pileafficher (Pile) ;
Merci pour votre aide !
J'ai quelque modifications à apporter à un scripte mais je n'y arrive pas. Le but de mon projet est de créer une pile en C au format LIFO ( last in first out ) consistant donc a ajouter / supprimer des éléments, le seul élément avec lequel on peut interagir étant celui se trouvant au sommet de la pile.
J'ai donc les scripts suivants:
//
// Fichier pile.h
//
#include <stdio.h>
#include <stdlib.h>
typedef float Element;
struct SCellule {
Element info;
struct SCellule *psuiv;
};
typedef struct SCellule *Cellule;
struct SPile{
struct SCellule *sommet;
int nbElements;
};
typedef struct SPile *Pile; Pile
PileVide();
Pile pileAjouter(Pile p, Element e);
Pile pileSupprimer(Pile p);
Element *pileSommet(Pile p);
int pileLongueur(Pile p);
//
// Fichier pile.c
//
#include "pile.h"
Pile pileVide(){
Pile p;
p=(Pile)malloc(sizeof(struct SPile));
p->nbElements = 0;
p->sommet = (Cellule) NULL;
return (p);
}
Pile pileAjouter(Pile p, Element e){
Cellule newSommet;
newSommet = (Cellule)malloc(sizeof(struct SCellule));
newSommet->info = e;
newSommet->psuiv = p->sommet;
p->sommet = newSommet;
p->nbElements=p->nbElements + 1;
return (p);
}
Pile pileSupprimer(Pile p){
Cellule tmp;
if(p->nbElements == 0){
return ((Pile)NULL);
}
tmp=p->sommet;
p->sommet = tmp->psuiv;
free(tmp);
p->nbElements = p->nbElements - 1;
return (p);
}
Element *pileSommet(Pile p){
if(p->nbElements == 0){
return ((Element*)NULL);
}
return &(p->sommet->info);
}
int pileLongueur(Pile p){
return p->nbElements;
}
[code]//
// Fichier main.c
//
#include "pile.h"
int main(){
Pile p; Element *elem;
int estSommet=0;
p=pileVide();
pileAjouter(p,1);
pileAjouter(p,2);
pileAjouter(p,3);
while(pileLongueur(p)>0){
if(estSommet == 0){
printf("\nLe sommet de la pile est %0.2f\n\n",*pileSommet(p));
estSommet=1;
}
printf("| %0.2f |\n", *pileSommet(p));
printf("------------\n");
pileSupprimer(p);
}
return (0);
}
[/code]
#
# Fichier Makefile
#
BIN = piles
OBJECTS = main.o pile.o
CC = gcc
all: $(OBJECTS)
$(CC) $(OBJECTS) -o $(BIN)
main.o: main.c pile.h
$(CC) -c main.c
vitesse.o : pile.h pile.c
$(CC) -c pile.c
clean:
rm -f $(OBJECTS) $(BIN) *~
J'obtient donc avec ce code :
//
// Résultat
//
Le sommet de la pile est 3.00
| 3.00 |
----------
| 2.00 |
----------
| 1.00 |
--------
Ce qui est correcte. Maintenant il faudrait que je remplace les élements 1,2,3 de ma pile par : (‘’fonction#1’’, 0x7F543210, ‘’Ok’’) a la place du 1, (fonction#2’’, 0x7F543220, ‘’987654’’) a la place du 2 et (‘’fonction#3’’, 0x7F543230, ‘’123456’’) a la place du 3. Mon code ne compilant que des éléments de type float j'ai essayé de convertir chaque ligne de type str en float avec la fonction strtof() mais celle ci ne converti que les nombres englobé dans dans "".
J'ai pensé a modifier la structure de l'élément de la façon suivante :
typedef struct {
char *first_string;
int integer_value;
char *second_string;
} Element;
Mais toujours rien.
Je dois donc avoir au final l'ordre d'execution suivant:
pileAjouter (‘’fonction#1’’, 0x7F543210, ‘’Ok’’) ;
pileAjouter (‘’fonction#2’’, 0x7F543220, ‘’987654’’) ;
pileAjouter (’fonction#3’’, 0x7F543230, ‘’123456’’) ;
pilelongueur (Pile) ;
pileafficher (Pile) ;
pileSupprimer (Pile) ;
pilelongueur(Pile) ;
pileafficher (Pile) ;
Merci pour votre aide !
Configuration: Windows / Chrome 94.0.4606.61
A voir également:
- Warning: format ‘%d’ expects a matching ‘int’ argument [-wformat=]
- Pile carte mere - Guide
- Pile bios empêche démarrage pc ✓ - Forum Matériel & Système
- Pile manette wii - Forum Wii
- Piles de la manette wii ✓ - Forum Bureautique
- Démarrer PC sans pile ✓ - Forum Matériel & Système
24 réponses
Donc au final j'obtiens:
Mais pour le résultat je n'obtient que les sommets et pas la pile en entière :
struct SCellule * c = p->sommet; Element el=c->info; c=c->psuiv printf("%s,0x%X,%x\n",el.first_string,el.integer_value,el.second_string);
Mais pour le résultat je n'obtient que les sommets et pas la pile en entière :
/// Résultat ///
Affichage des 3 élement(s) de la pile:
fonction#3,0x7F543230,12456
Affichage des 2 élement(s) de la pile:
fonction#2,0x7F543230,987654
Au moins a force de rester en face de mon pc j'ai enfin fini par trouver quelque chose qui marche xD !
Avec les fichiers suivants :
et
J'obtiens le résultat attendu :
Vraiment merci d'avoir pris autant de ton temps pour m'aider et désolé si parfois je mettais t'as patience à rude épreuve … J'ai appris plus avec toi en une semaine qu'avec un professeur que j'ai depuis plus d'un semestre alors merci encore!
Avec les fichiers suivants :
/// /// ///main.c /// /// /// include "pile.h" int main() { Pile p; Element *elem; int estSommet=0; p=pileVide(); struct Element el1; el1.first_string="fonction#1"; el1.integer_value=0x7F543210; el1.second_string="Ok"; struct Element el2; el2.first_string="fonction#2"; el2.integer_value=0x7F543220; el2.second_string="987654"; struct Element el3; el3.first_string="fonction#3"; el3.integer_value=0x7F543230; el3.second_string="123456"; pileAjouter(p,el1); pileAjouter(p,el2); pileAjouter(p,el3); printf("\n-----------------DEBUT-----------------\n\n"); printf("1. Initialisation d'une pile\n"); pileAfficher(p); printf("\n2. On dépile un élement de la pile\n"); pileSupprimer(p); pileAfficher(p); printf("\n-----------------FIN-----------------\n"); }
et
#include "pile.h" // // Fichier piles.c // Pile pileVide(){ Pile p; p=(Pile)malloc(sizeof(struct SPile)); p->nbElements = 0; p->sommet = (Cellule) NULL; return (p); } Pile pileAjouter(Pile p, Element e){ Cellule newSommet; newSommet = (Cellule)malloc(sizeof(struct SCellule)); newSommet->info = e; newSommet->psuiv = p->sommet; p->sommet = newSommet; p->nbElements=p->nbElements + 1; return (p); } Pile pileSupprimer(Pile p){ Cellule tmp; if(p->nbElements == 0){ return ((Pile)NULL); } tmp=p->sommet; p->sommet = tmp->psuiv; free(tmp); p->nbElements = p->nbElements - 1; return (p); } Element pileSommet(Pile p){ if(p->nbElements == 0){ return ((Element)NULL); } return &(p->sommet->info); } int pileLongueur(Pile p){ return p->nbElements; } void pileAfficher(Pile p){ int nbElements=p->nbElements; if(p==NULL) { exit(EXIT_FAILURE); } if(nbElements<1) { printf("La pile est vide rien à afficher \n"); return; } printf("\nEtat de la pile:\n"); printf("\nAddresse de la pile: 0x%p\n",p); printf("Affichage des %d élément(s) de la pile:\n\n", nbElements); struct SCellule *c=p->sommet; while(c != NULL) { Element el= c->info; c=c->psuiv; printf("%s,0x%X,%s\n",el.first_string,el.integer_value,el.second_string); } }
J'obtiens le résultat attendu :
/// Résultat ///
------------------- DEBUT------------------------------
1. Initialisation d'une pile
Etat de la pile:
Addresse de la pile: 0x0x55763dc802a0
Affichage des 3 élément(s) de la pile:
fonction#3,0x7F543230,12456
fonction#2,0x7F543230,987654
fonction#1,0x7F543210,Ok
2. On dépile un élément de la pile
Etat de la pile:
Addresse de la pile: 0x0x55763dc802a0
Affichage des 2 élement(s) de la pile:
fonction#2,0x7F543230,987654
fonction#1,0x7F543210,Ok
------------------- FIN------------------------------
Vraiment merci d'avoir pris autant de ton temps pour m'aider et désolé si parfois je mettais t'as patience à rude épreuve … J'ai appris plus avec toi en une semaine qu'avec un professeur que j'ai depuis plus d'un semestre alors merci encore!
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
11 oct. 2021 à 14:51
11 oct. 2021 à 14:51
Salut AviateurRex,
Pas de problème. Je suis content si tu as appris des choses grâce à nos échanges.
Bonne continuation
Pas de problème. Je suis content si tu as appris des choses grâce à nos échanges.
Bonne continuation
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
1 oct. 2021 à 10:12
1 oct. 2021 à 10:12
Salut AviateurRex,
Ce n'est pas un "script", car le C est un langage compilé, et non un langage de script interprété.
Mon code ne compilant que des éléments de type float
Est-ce bien ton code que tu montres ?
j'ai essayé de convertir chaque ligne de type str en float avec la fonction strtof() mais celle ci ne converti que les nombres englobé dans dans "".
Cela ne peut pas marcher. De plus tu as 3 éléments. Il faut bien une struct pour en faire un élément.
J'ai pensé a modifier la structure de l'élément de la façon suivante :
typedef struct {
char *first_string;
int integer_value;
char *second_string;
} Element;
Mais toujours rien.
Que veux-tu dire par "Mais toujours rien" ? Peux-tu montrer ton code adapté pour stocker des struct dans ta pile ? Autrement, on ne sait pas quel est réellement ton problème.
Dal
Ce n'est pas un "script", car le C est un langage compilé, et non un langage de script interprété.
Mon code ne compilant que des éléments de type float
Est-ce bien ton code que tu montres ?
j'ai essayé de convertir chaque ligne de type str en float avec la fonction strtof() mais celle ci ne converti que les nombres englobé dans dans "".
Cela ne peut pas marcher. De plus tu as 3 éléments. Il faut bien une struct pour en faire un élément.
J'ai pensé a modifier la structure de l'élément de la façon suivante :
typedef struct {
char *first_string;
int integer_value;
char *second_string;
} Element;
Mais toujours rien.
Que veux-tu dire par "Mais toujours rien" ? Peux-tu montrer ton code adapté pour stocker des struct dans ta pile ? Autrement, on ne sait pas quel est réellement ton problème.
Dal
[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 1 oct. 2021 à 10:29
Modifié le 1 oct. 2021 à 10:29
D'autre part, dans ton pile.h, je pense qu'il y a un problème à la ligne 31, où tu indiques un prototype
Le C est un langage sensible à la casse.
PileVide();ne correspondant pas à la fonction
Pile pileVide()définie dans pile.c
Le C est un langage sensible à la casse.
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
1 oct. 2021 à 20:36
1 oct. 2021 à 20:36
La seule modification à faire au module pile (le couple pile.c et pile.h) est en pile.h :
Ensuite, il faut, bien sûr des changements au main.c, puisqu'il faut :
et c'est tout.
à quel stade as-tu un problème ?
Dal
- le typedef pour Element, qu'il faut remplacer par celui que tu mentionnes
- un prototype PileVide(); qu'il faut orthographier correctement avec un p minuscule
Ensuite, il faut, bien sûr des changements au main.c, puisqu'il faut :
- initialiser des struct avec les Elements gérés
- insérer les struct dans la pile
- afficher les informations les concernant correctement
et c'est tout.
à quel stade as-tu un problème ?
Dal
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Déjà merci énormément de prendre de votre temps pour me répondre vous imaginez même pas a quel point vous m'aider. Le langage C est un nouveau langage et j'avoue que j'arrive à être bloquer assez vite dessus. Pourtant j'essaye de comprendre en lisant des cours / ex sur les piles mais j'ai du mal.
En fait le soucis que j'ai c'est qu'une fois que j'ai adopté la structure :
Je n'arrive pas à initialiser les éléments dans le format de ma nouvelle structure ( dans mon main.c donc ) et par conséquent je n'arrive pas non plus à effectuer la liste d'instruction qui suit avec ajouter,supprimer etc.
En fait le soucis que j'ai c'est qu'une fois que j'ai adopté la structure :
typedef struct {
char *first_string;
int integer_value;
char *second_string;
} Element;
Je n'arrive pas à initialiser les éléments dans le format de ma nouvelle structure ( dans mon main.c donc ) et par conséquent je n'arrive pas non plus à effectuer la liste d'instruction qui suit avec ajouter,supprimer etc.
Dalfab
Messages postés
706
Date d'inscription
dimanche 7 février 2016
Statut
Membre
Dernière intervention
2 novembre 2023
101
2 oct. 2021 à 12:21
2 oct. 2021 à 12:21
Bonjour,
Je te propose de simplifier le code en utilisant plutôt comme structure:
Ensuite après avoir modifié l'interface de
Je te propose de simplifier le code en utilisant plutôt comme structure:
typedef struct { char first_string[30]; int integer_value; char second_string[30]; } Element;Celle-ci est moins souple mais te permettra d'éviter de passer par des
malloc().
Ensuite après avoir modifié l'interface de
Pile pileAjouter(Pile p, ....)pour qu'elle corresponde à ton besoin, il ne reste qu'à appliquer ce que t'a indiqué Dal. C'est très peu de choses.
Du coup, j'ai bien corrigé mon erreur dans le pile.h pour la fonction Pile pileVide(); que j'avais mal saisie comme l'a mentionné Dal, j'ai modifié la structure de l'élément comme l'a suggéré Dalfab. J'ai aussi supprimé tous les malloc() du pile.c. J'ai essayé de modifier mon main.c pour ajouter mes éléments avec leurs nouvelle structure mais je n'y arrive toujours pas, j'essaye de déclarer mes variables mais j'ai encore pleins d'erreurs :
gcc -c main.c
main.c: In function ‘main’:
main.c:12:2: error: ‘val_1’ undeclared (first use in this function)
12 | val_1=("fonction#1", 0x7F543210, "Ok");
| ^~~
main.c:12:2: note: each undeclared identifier is reported only once for each function it appears in
main.c:13:2: error: ‘val_2’ undeclared (first use in this function)
13 | val_2=("fonction#2", 0x7F543220, "987654");
| ^
main.c:14:2: error: ‘val_3’ undeclared (first use in this function)
14 | val_3=("fonction#3", 0x7F543230, "123456");
| ^
main.c:23:43: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘Element’ {aka ‘struct <anonymous>’} [-Wformat=]
23 | printf("\nLe sommet de la pile est %0.2f\n\n",*pileSommet(p));estSommet=1;
| ^ ~~
| | |
| double Element {aka struct <anonymous>}
main.c:27:17: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘Element’ {aka ‘struct <anonymous>’} [-Wformat=]
27 | printf("| %0.2f |\n", *pileSommet(p));
| ^ ~~~~
| | |
| double Element {aka struct <anonymous>}
J'ai continué et je suis désolé d'avoir été autant largué ! J'ai bien suivis vos conseils et j'approche enfin de quelque chose mais une erreur me bloque... j'ai donc finalement repris la structure:
Je ne sais pas pourquoi celle que Dalfab avait renseigné ne marchait pas. J'ai donc rajouter à mon main.c les lignes suivantes pour pouvoir définir mes élements :
Mais pour les 3 fonctions, j'ai la même erreur : storage size of "fonction " isn't known. Jj'ai vu que ce problème venait souvent par la déclaration des structures pourtant la mienne respecte bien la forme struct NomDeLaStructure NomDeL'argument .
typedef struct {
char *first_string;
int integer_value;
char *second_string;
} Element;
Je ne sais pas pourquoi celle que Dalfab avait renseigné ne marchait pas. J'ai donc rajouter à mon main.c les lignes suivantes pour pouvoir définir mes élements :
struct Element fonction1;
fonction1.first_string= "Fonction#1";
fonction1.integer_value=0x7F543210;
fonction1.second_string= "Ok";
struct Element fonction2;
fonction1.first_string= "Fonction#2";
fonction1.integer_value=0x7F543220;
fonction1.second_string= "987654";
struct Element fonction3;
fonction1.first_string= "Fonction#3";
fonction1.integer_value=0x7F543230;
fonction1.second_string= "123456";
pileAjouter(p,fonction1);
pileAjouter(p,fonction2);
pileAjouter(p,fonction3);
Mais pour les 3 fonctions, j'ai la même erreur : storage size of "fonction " isn't known. Jj'ai vu que ce problème venait souvent par la déclaration des structures pourtant la mienne respecte bien la forme struct NomDeLaStructure NomDeL'argument .
[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 5 oct. 2021 à 11:40
Modifié le 5 oct. 2021 à 11:40
Bonjour AviateurRex,
Merci de finalement montrer un bout de code. Si tu ne le fais pas on en est réduits aux suppositions sur la nature de tes problèmes, même si certains messages d'erreurs peuvent nous renseigner.
Tout d'abord, ne supprime pas les malloc() dans pile.c
L'indication de Dalfab portait sur ton code dans main.c : pour te faciliter la vie dans ton code et t'éviter d'avoir à gérer des pointeurs et une allocation dynamique éventuellement nécessaire pour stocker tes chaînes.
Ensuite, s'agissant de ton erreur, elle vient du fait que tu déclares tes variables avec un type non connu.
Avec le code suivant :
tu fais 2 choses :
Si tu veux utiliser ce type, tu dois utiliser l'alias en tant que type, comme ceci :
Si tu avais défini un type struct avec son étiquette, comme il se doit, tu pourrais utiliser le type struct pour définir tes variables.
tu utilises le type struct Element comme ceci :
Si tu veux pouvoir définir tes variables soit avec l'alias typedef, soit avec le nom de la struct, tu peux définir ton type comme ceci :
Merci de finalement montrer un bout de code. Si tu ne le fais pas on en est réduits aux suppositions sur la nature de tes problèmes, même si certains messages d'erreurs peuvent nous renseigner.
Tout d'abord, ne supprime pas les malloc() dans pile.c
L'indication de Dalfab portait sur ton code dans main.c : pour te faciliter la vie dans ton code et t'éviter d'avoir à gérer des pointeurs et une allocation dynamique éventuellement nécessaire pour stocker tes chaînes.
Ensuite, s'agissant de ton erreur, elle vient du fait que tu déclares tes variables avec un type non connu.
Avec le code suivant :
typedef struct { char *first_string; int integer_value; char *second_string; } Element;
tu fais 2 choses :
- tu crées une struct anonyme (qui n'a pas d'étiquette après le mot clef struct)
- et tu crées un type qui est un alias de cette struct et que tu nommes Element.
Si tu veux utiliser ce type, tu dois utiliser l'alias en tant que type, comme ceci :
Element fonction1;...
Si tu avais défini un type struct avec son étiquette, comme il se doit, tu pourrais utiliser le type struct pour définir tes variables.
struct Element { char *first_string; int integer_value; char *second_string; };
tu utilises le type struct Element comme ceci :
struct Element fonction1;...
Si tu veux pouvoir définir tes variables soit avec l'alias typedef, soit avec le nom de la struct, tu peux définir ton type comme ceci :
typedef struct Element { char *first_string; int integer_value; char *second_string; } Element;
[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
Modifié le 5 oct. 2021 à 12:24
Modifié le 5 oct. 2021 à 12:24
attention aussi à tes copier-collers.
Si tu initialises 3 fois les valeurs internes à la struct pour la même variable "fonction1" comme tu le fais, en oubliant de faire changer le nom des variables que tu est censé initialiser ensuite en "fonction2" et "fonction3", ces dernières ne sont pas initialisées et contiendront quelque chose qui ne conviendra pas.
(en passant, tu devrais vraiment choisir un autre nom, car appeler un élément d'une liste "fonction" est très moyen, par exemple el1, el2, el3 auraient ma préférence et feraient mieux l'affaire)
Si tu initialises 3 fois les valeurs internes à la struct pour la même variable "fonction1" comme tu le fais, en oubliant de faire changer le nom des variables que tu est censé initialiser ensuite en "fonction2" et "fonction3", ces dernières ne sont pas initialisées et contiendront quelque chose qui ne conviendra pas.
(en passant, tu devrais vraiment choisir un autre nom, car appeler un élément d'une liste "fonction" est très moyen, par exemple el1, el2, el3 auraient ma préférence et feraient mieux l'affaire)
[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
5 oct. 2021 à 12:33
5 oct. 2021 à 12:33
autre remarque, dans ton message d'origine, tu disais :
il faudrait que je remplace les élements 1,2,3 de ma pile par : (‘’fonction#1’’, 0x7F543210, ‘’Ok’’) a la place du 1, (fonction#2’’, 0x7F543220, ‘’987654’’) a la place du 2 et (‘’fonction#3’’, 0x7F543230, ‘’123456’’) a la place du 3
Si tu mets dans ton champ first_string de chaque variable un pointeur vers des chaînes "Fonction#1", "Fonction#2" et "Fonction#3" avec un "F" et non pas un "f" tu ne fais peut-être pas que qu'on te dit de faire ... enfin, c'est toi qui vois ce que tu dois faire :-)
il faudrait que je remplace les élements 1,2,3 de ma pile par : (‘’fonction#1’’, 0x7F543210, ‘’Ok’’) a la place du 1, (fonction#2’’, 0x7F543220, ‘’987654’’) a la place du 2 et (‘’fonction#3’’, 0x7F543230, ‘’123456’’) a la place du 3
Si tu mets dans ton champ first_string de chaque variable un pointeur vers des chaînes "Fonction#1", "Fonction#2" et "Fonction#3" avec un "F" et non pas un "f" tu ne fais peut-être pas que qu'on te dit de faire ... enfin, c'est toi qui vois ce que tu dois faire :-)
Merci énormément pour toute ton aide Dal ! Je vais m'y remettre et je vous tiendrai au courant de mon avancé.
EDIT
J'ai donc modifié ma structure comme tu l'as dis et j'ai aussi changé mon main.c et j'obtiens au final :
Bonne nouvelle, je n'ai plus d'erreur en compilant, mauvais nouvelle la pile que je reçois est :
J'ai donc modifié ma structure comme tu l'as dis et j'ai aussi changé mon main.c et j'obtiens au final :
#include "pile.h"
int main(int argc, char *argv[])
{
printf("1. INITIALISATION DE LA PILE");
Pile p;
Element *elem;
int estSommet=0;
p=pileVide();
struct Element el1;
el1.first_string="fonction#1";
el1.integer_value=0x7F543210;
el1.second_string="Ok";
struct Element el2;
el2.first_string="fonction#2";
el2.integer_value=0x7F543220;
el2.second_string="987654";
struct Element el3;
el3.first_string="fonction#3";
el3.integer_value=0x7F543230;
el3.second_string="123456";
pileAjouter(p,el1);
pileAjouter(p,el2);
pileAjouter(p,el3);
while(pileLongueur(p)>0){
if(estSommet == 0){
printf("\nLe sommet de la pile est %0.2f\n\n",*pileSommet(p));estSommet=1;
}
printf("| %0.2f |\n", *pileSommet(p));
printf("---------\n");
pileSupprimer(p);
}
return (0);
}
Bonne nouvelle, je n'ai plus d'erreur en compilant, mauvais nouvelle la pile que je reçois est :
Le sommet de la pile est 0.00
| 0.00 |
----------
| 0.00 |
----------
| 0.00 |
--------
Lors de l'exécution tout à l'heure aucune erreur et la j'en ai, elles n'apparaissent pas à chaque compilage.
J'ai donc les erreurs suivantes :
Ce qui me semble cohérent puisque c'est l'affichage qui me pose problème.
J'ai donc les erreurs suivantes :
gcc -c main.c
main.c: In function ‘main’:
main.c:39:41: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘Element’ {aka ‘struct Element’} [-Wformat=]
39 | printf("Le sommet de la pile est %0.2f\n\n",*pileSommet(p));estSommet=1;
| ~~^ ~~
| | |
| double Element {aka struct Element}
main.c:43:17: warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘Element’ {aka ‘struct Element’} [-Wformat=]
43 | printf( "|%0.2f|\n", *pileSommet(p));
| ^ ~~~~
| | |
| double Element {aka struct Element}
Ce qui me semble cohérent puisque c'est l'affichage qui me pose problème.
[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 5 oct. 2021 à 20:50
Modifié le 5 oct. 2021 à 20:50
Salut,
Ce que tu postes sont des avertissements et non des erreurs. Cela signifie que ton code est syntaxiquement correct et peut générer un exécutable, en raison de la souplesse du langage C, mais que ce que écris n'a pas beaucoup de sens à moins que tu saches très exactement ce que tu fais et que dans 90% des cas c'est très certainement erroné.
Tu devrais toujours compiler avec les warnings en mettant au minimum l'option
Ensuite, tu dois compiler non seulement main.c, mais aussi pile.c, qui est le module dont tu utilises les fonctions accessibles par l'entête pile.h.
Enfin, l'option de ligne de commande -c sert juste à compiler, et pas à générer un exécutable.
Ta ligne de commande devrait être pour compiler les fichiers utiles et les lier pour produire un exécutable :
Si tu es sous Linux et que la compilation réussit, tu devrais avoir un fichier créé sous le nom par défaut
Si tu veux choisir un autre nom d'exécutable, tu l'indiques en ligne de commande avec l'option
Maintenant, que te disent les warnings.
Tu as un conflit de types, car ton printf() comporte un spécificateur pour afficher un nombre flottant, alors que tu passes en argument une struct.
Que veux tu afficher réellement ?
Ce que tu postes sont des avertissements et non des erreurs. Cela signifie que ton code est syntaxiquement correct et peut générer un exécutable, en raison de la souplesse du langage C, mais que ce que écris n'a pas beaucoup de sens à moins que tu saches très exactement ce que tu fais et que dans 90% des cas c'est très certainement erroné.
Tu devrais toujours compiler avec les warnings en mettant au minimum l'option
-Wallsystématiquement, et toujours prendre en compte ce qu'ils disent.
Ensuite, tu dois compiler non seulement main.c, mais aussi pile.c, qui est le module dont tu utilises les fonctions accessibles par l'entête pile.h.
Enfin, l'option de ligne de commande -c sert juste à compiler, et pas à générer un exécutable.
Ta ligne de commande devrait être pour compiler les fichiers utiles et les lier pour produire un exécutable :
gcc -Wall main.c pile.c
Si tu es sous Linux et que la compilation réussit, tu devrais avoir un fichier créé sous le nom par défaut
a.outque tu peux lancer un ligne de commande en tapant
./a.out. SI tu es sous Windows, c'est un .exe qui est créé.
Si tu veux choisir un autre nom d'exécutable, tu l'indiques en ligne de commande avec l'option
-o. Par exemple, sous Linux pour avoir un exécutable dénommé simplement "piles" :
gcc -Wall main.c pile.c -o piles
Maintenant, que te disent les warnings.
Tu as un conflit de types, car ton printf() comporte un spécificateur pour afficher un nombre flottant, alors que tu passes en argument une struct.
Que veux tu afficher réellement ?
AviateurRex
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
6 oct. 2021 à 05:32
6 oct. 2021 à 05:32
Le seul soucis que j'ai du coup c'est les printf, je veux afficher les éléments de ma structure (el1,el2,el3). J'ai pensé à faire :
Mais je n'y arrive pas.
Du coup il faudrait que j'arrive à :
- ajouter mes éléments ( ce qui est fait avec les el1,el2,el3)
- afficher tous mes éléments et mettre en évidence le sommet de la pile
- supprimer le dernier élément
- afficher la pile avec les éléments et le nouveau sommet
printf( " fonction1 = %s\n", el1.first_string);
printf( " 0x7F543210 = %s\n", el1.integer_value);
printf( " Ok = %s\n", el1.second_string);
Mais je n'y arrive pas.
Du coup il faudrait que j'arrive à :
- ajouter mes éléments ( ce qui est fait avec les el1,el2,el3)
- afficher tous mes éléments et mettre en évidence le sommet de la pile
- supprimer le dernier élément
- afficher la pile avec les éléments et le nouveau sommet
EDIT
Pour te donner une idée du résultat je devrai obtenir quelque chose qui ressemble à ça :
Pour te donner une idée du résultat je devrai obtenir quelque chose qui ressemble à ça :
1.1 Affichage de la pile
Le sommet de la pile est "fonction#3’’, 0x7F543230, ‘’123456’’
|"fonction#3’’, 0x7F543230, ‘’123456’’|
--------------------------------------------------------------
|‘’fonction#2’’, 0x7F543220, ‘’987654’’|
-------------------------------------------------------------
|‘’fonction#1’’, 0x7F543210, ‘’Ok’’ |
------------------------------------------------------------
1.2 Affichage de la pile (le dernier élément supprimé )
Le sommet de la pile est ‘’fonction#2’’, 0x7F543220, ‘’987654’’
|‘’fonction#2’’, 0x7F543220, ‘’987654’’|
------------------------------------------------------------
|‘’fonction#1’’, 0x7F543210, ‘’Ok’’ |
------------------------------------------------------------
[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 6 oct. 2021 à 17:27
Modifié le 6 oct. 2021 à 17:27
Tu as deux difficultés. La première est de trouver le bon spécificateur de format pour ce que tu veux afficher.
https://www.cplusplus.com/reference/cstdio/printf/
Selon cette documentation, qui donne des exemples comprenant presque exactement ce même cas, tu dois pouvoir utiliser un spécificateur %#X pour avoir des résultats comme 0X7F543230 ou %#x pour avoir des résultats comme 0x7f543230. A toi de voir si l'un des deux peut convenir.
Le C peut gérer le préfixage automatique de 0X ou 0x pour toi, mais pas de la façon exacte attendue 0x7F543230 (avec un 0x minuscule et des lettres majuscules dans le nombre hexa).
Si tu veux effectivement 0x7F543230 tu peux simplement utiliser le spécificateur %X pour disposer d'un affichage de type 7F543230 et précéder ce spécificateur des caractères 0x, donc : 0x%X, ce qui affiche la suite de caractères exactement voulue.
Plus qu'une difficulté, c'est accéder aux différents membres de la struct à partir de ce que te renvoie pileSommet(p).
Le prototype de cette fonction est
Si tu te fies à l'exemple initial dont tu disposes, tu devrais donc :
mais tu dois aussi prendre en compte les règles de préséance et associativité des opérateurs en C pour l'opérateur
https://en.cppreference.com/w/c/language/operator_precedence
Il y a aussi un moyen plus simple de déréférencer un pointeur sur une struct pour accéder à un de ses membres, c'est d'utiliser l'opérateur
Tu as tous les éléments désormais. A ton avis comment faut-il écrire un printf() pour afficher, par exemple le membre first_string à partir de ce que te renvoie pileSommet(p) ?
- Tu dois afficher deux chaînes, pour elles le spécificateur de format de printf() est bien %s
- Tu dois afficher un entier en base hexadécimale avec des lettres majuscules précédé de 0x. Pour afficher cela, tu ne peux pas utiliser %s comme tu le proposes, qui est réservé aux chaînes C.
https://www.cplusplus.com/reference/cstdio/printf/
Selon cette documentation, qui donne des exemples comprenant presque exactement ce même cas, tu dois pouvoir utiliser un spécificateur %#X pour avoir des résultats comme 0X7F543230 ou %#x pour avoir des résultats comme 0x7f543230. A toi de voir si l'un des deux peut convenir.
Le C peut gérer le préfixage automatique de 0X ou 0x pour toi, mais pas de la façon exacte attendue 0x7F543230 (avec un 0x minuscule et des lettres majuscules dans le nombre hexa).
Si tu veux effectivement 0x7F543230 tu peux simplement utiliser le spécificateur %X pour disposer d'un affichage de type 7F543230 et précéder ce spécificateur des caractères 0x, donc : 0x%X, ce qui affiche la suite de caractères exactement voulue.
Plus qu'une difficulté, c'est accéder aux différents membres de la struct à partir de ce que te renvoie pileSommet(p).
Le prototype de cette fonction est
Element *pileSommet(Pile p), elle renvoie donc un pointeur vers Element, c'est à dire, dans notre cas, un pointeur sur une struct.
Si tu te fies à l'exemple initial dont tu disposes, tu devrais donc :
- déréférencer ce pointeur avec l'opérateur
*
pour accéder à l'élément - utiliser l'opérateur
.
pour accéder au membre souhaité
mais tu dois aussi prendre en compte les règles de préséance et associativité des opérateurs en C pour l'opérateur
.et
*...
https://en.cppreference.com/w/c/language/operator_precedence
Il y a aussi un moyen plus simple de déréférencer un pointeur sur une struct pour accéder à un de ses membres, c'est d'utiliser l'opérateur
->qui évite de se prendre la tête avec les deux opérateurs précédents, qui ne discutent pas bien ensemble. C'est un raccourci bien pratique créé par le langage C car il est fréquent de devoir déréférencer un pointeur sur une struct pour accéder à un de ses membres.
Tu as tous les éléments désormais. A ton avis comment faut-il écrire un printf() pour afficher, par exemple le membre first_string à partir de ce que te renvoie pileSommet(p) ?
AviateurRex
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
7 oct. 2021 à 07:42
7 oct. 2021 à 07:42
Pour le problème d'affichage de la base hexadécimale j'ai bien compris de quoi il était question, par contre pour le second j'avoue que je saisie pas très bien l'histoire de déréférencement ... Je vois pas vraiment la structure que le printf peut avoir.
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
>
AviateurRex
7 oct. 2021 à 09:27
7 oct. 2021 à 09:27
- si tu ne sais pas ce que signifie "déréférencer un pointeur", c'est probablement que tu ne sais pas ce qu'est un pointeur, ni comment l'utiliser
ton code d'origine déréférence le pointeur sur.float renvoyé par pileSommet(p) en faisant
*pileSommet(p)c'est à dire avec l'opérateur
*dans la ligne
printf("| %0.2f |\n", *pileSommet(p));...
Tu devrais vraiment regarder ton manuel de C sur les pointeurs ou ton cours. C'est très gênant, en C, de ne pas savoir utiliser les pointeurs.
- regarde aussi, ensuite, les pointeurs sur les struct et la notation spéciale
->
Si tu veux une explication générale sur les pointeurs, je peux te la donner, mais cela m'étonne beaucoup que tu n'en disposes pas déjà quelque part.
Le but de mon projet est de créer une pile en C au format LIFO ( last in first out ) consistant donc a ajouter / supprimer des éléments, le seul élément avec lequel on peut interagir étant celui se trouvant au sommet de la pile.
dans quel contexte fais tu ce projet ?
AviateurRex
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
7 oct. 2021 à 09:58
7 oct. 2021 à 09:58
C'est un devoir à rendre, je suis en licence informatique et je dois rendre ce devoir pour mardi au plus tard. Ce devoir c'est vraiment le 1er code que je fais en C, et pour ce qui est du cours je n'en n'ai pas, c'est bien pour ça que j'ai du mal à intégrer toutes ces nouvelles notions. J'ai appris bien plus sur ce forum qu'avec mon professeur qui ne nous communique pas grand chose.
Le code que j'avais au départ, c'est un code que j'ai plus ou moins fait en me basant sur divers exemple sur internet, je ne savais même pas au départ que je devais créer un fichier .h pour définir mes structures donc autant dire que je viens de loin ... Dans l'ensemble j'ai assez bien compris l'élaboration des fonctions et l'implémentation des structures dans moi main mais pour l'affichage la j'ai du mal.
Le code que j'avais au départ, c'est un code que j'ai plus ou moins fait en me basant sur divers exemple sur internet, je ne savais même pas au départ que je devais créer un fichier .h pour définir mes structures donc autant dire que je viens de loin ... Dans l'ensemble j'ai assez bien compris l'élaboration des fonctions et l'implémentation des structures dans moi main mais pour l'affichage la j'ai du mal.
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
>
AviateurRex
Modifié le 7 oct. 2021 à 11:52
Modifié le 7 oct. 2021 à 11:52
OK, c'est étonnant qu'on ne t'explique pas les pointeurs en C, ou qu'on ne te donne pas un cours ou un manuel, ouvrage ou de site de référence auquel tu puisse te référer.
Voilà une explication très générale sur les pointeurs en C.
Un pointeur est juste un moyen en langage C d'accéder indirectement à un contenu d'un certain type stocké en mémoire au moyen de son adresse mémoire. C'est tout.
Un type
Dans le code d'origine pileSommet() renvoie un pointeur sur float et le printf() utilise le contenu retourné par cette fonction en la précédant de l'opérateur
Vois :
https://zestedesavoir.com/tutoriels/755/le-langage-c-1/1043_aggregats-memoire-et-fichiers/4277_les-pointeurs/
puis :
https://zestedesavoir.com/tutoriels/755/le-langage-c-1/1043_aggregats-memoire-et-fichiers/4279_structures/#2-structures-et-pointeurs
où tu verras qu'il est préférable, pour les pointeurs sur struct, de ne pas utiliser l'opérateur d'indirection
Si tu es en licence informatique, tu as dû apprendre à maîtriser plusieurs langages et tu dois être en mesure de saisir le fonctionnement d'autres langages avec des paradigmes similaires par tes propres efforts en consultant des documents de référence comme ceux que tu trouves sur les liens que je t'ai donnés :
https://www.cplusplus.com/reference/cstdio/printf/
https://en.cppreference.com/w/c/language/operator_precedence
Ou en suivant des tutoriels simples comme celui de ZdS qui est bien fait pour mettre le pied à l'étrier de débutants complets en programmation, qui devrait donc être très largement à ton niveau :-)
Voilà une explication très générale sur les pointeurs en C.
Un pointeur est juste un moyen en langage C d'accéder indirectement à un contenu d'un certain type stocké en mémoire au moyen de son adresse mémoire. C'est tout.
Un type
Element *signifie "un pointeur vers un contenu de type
Element".
Dans le code d'origine pileSommet() renvoie un pointeur sur float et le printf() utilise le contenu retourné par cette fonction en la précédant de l'opérateur
*qui est l'opérateur d'indirection du C, permettant de déréférencer l'adresse mémoire et d'accéder au contenu pointé par cette adresse. Au final, ce qui est passé en argument de printf() est le float (auquel on a accédé indirectement) et comme cela correspond bien au spécificateur de printf()
%f, l'affichage est correct.
Vois :
https://zestedesavoir.com/tutoriels/755/le-langage-c-1/1043_aggregats-memoire-et-fichiers/4277_les-pointeurs/
puis :
https://zestedesavoir.com/tutoriels/755/le-langage-c-1/1043_aggregats-memoire-et-fichiers/4279_structures/#2-structures-et-pointeurs
où tu verras qu'il est préférable, pour les pointeurs sur struct, de ne pas utiliser l'opérateur d'indirection
*en raison des complications de syntaxe qu'il suppose utilisé conjointement avec
.et d'utiliser l'opérateur
->et qui est beaucoup plus pratique pour déréférencer un pointeur sur une struct lorsqu'on veut accéder à un de ses membres.
Si tu es en licence informatique, tu as dû apprendre à maîtriser plusieurs langages et tu dois être en mesure de saisir le fonctionnement d'autres langages avec des paradigmes similaires par tes propres efforts en consultant des documents de référence comme ceux que tu trouves sur les liens que je t'ai donnés :
https://www.cplusplus.com/reference/cstdio/printf/
https://en.cppreference.com/w/c/language/operator_precedence
Ou en suivant des tutoriels simples comme celui de ZdS qui est bien fait pour mettre le pied à l'étrier de débutants complets en programmation, qui devrait donc être très largement à ton niveau :-)
Je commence enfin à en voir la fin de ce code ! x) Bon c'est toujours pas fini mais déjà les pointeurs ne me semble plus inconnu. Pour l'instant j'arrive juste à afficher :
J'arrive pas à comprendre comment structurer mon code avant la fonction Pilesommet(p) en fait.
Par exemple dans cette partie la :
Je ne comprend pas comment mettre les données de el3. Parceque la, la fonction Pilesommet(p) a un pointeur * vers mon Element qui est à la structure char,int,char. je dois forcément mettre %s,0x%x,%s ,el3.first_string,el3.ineger_value,el3.second_string dans mon print non ?
Et pour l'affichage des el1,el2,el3 je pense qu'il ne marche pas à cause de Pilesommet(p).
J'ai le code suivant pour l'instant :
Le sommet de la pile est
|‘’fonction#1’’, 0x7F543210, ‘’Ok’’ |
--------------------------------------------------------------
|‘’fonction#1’’, 0x7F543210, ‘’Ok’’ |
-------------------------------------------------------------
|‘’fonction#1’’, 0x7F543210, ‘’Ok’’ |
------------------------------------------------------------
J'arrive pas à comprendre comment structurer mon code avant la fonction Pilesommet(p) en fait.
Par exemple dans cette partie la :
while(pileLongueur(p)>0){
if(estSommet == 0){
printf("\nLe sommet de la pile est "mettre les données de el3"\n\n",*pileSommet(p));estSommet=1;
Je ne comprend pas comment mettre les données de el3. Parceque la, la fonction Pilesommet(p) a un pointeur * vers mon Element qui est à la structure char,int,char. je dois forcément mettre %s,0x%x,%s ,el3.first_string,el3.ineger_value,el3.second_string dans mon print non ?
Et pour l'affichage des el1,el2,el3 je pense qu'il ne marche pas à cause de Pilesommet(p).
J'ai le code suivant pour l'instant :
while(pileLongueur(p)>0){
if(estSommet == 0){
printf("Le sommet de la pile est \n\n",*pileSommet(p)); estSommet=1;
}
printf( "|%s,0x%x,%s|\n",el1.first_string,el1.integer_value,el1.second_string) ;
printf("---------\n");
pileSupprimer(p);
}
return (0);
}
[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 7 oct. 2021 à 13:02
Modifié le 7 oct. 2021 à 13:02
le but du while est de faire fonctionner la pile, en :
tu ne dois donc pas y utiliser les variables el1, el2 ou el3, dont le contenu est déjà accessible par la pile.
Comme dans ton code de départ, tu dois utiliser ce qui est renvoyé par pileSommet()
- utilisant une fonction qui renvoie l'élément au sommet
- utilisant une fonction qui dépile cet élément pour passer au suivant
- tant qu'il y a quelque chose dans la pile
tu ne dois donc pas y utiliser les variables el1, el2 ou el3, dont le contenu est déjà accessible par la pile.
Comme dans ton code de départ, tu dois utiliser ce qui est renvoyé par pileSommet()
AviateurRex
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
7 oct. 2021 à 13:37
7 oct. 2021 à 13:37
Dans mon code initial, la méthode utilisé dans le printf() était avec %0.2f était utilisé avec 0.2 pour donner la précision voulue et f pour le type de donnée utilisée. pileSommet() pointe la
structure, donc pourquoi quand je renseigne :
j'ai une erreur :
L'erreur me dit bien que pileSOmmet() pointe vers Element alors pourquoi n'arrive t'il pas a afficher les elements de la structure ?
structure, donc pourquoi quand je renseigne :
printf("Le sommet de la pile est %s,0x%x,%s \n\n",*pileSommet(p)); estSommet=1;
j'ai une erreur :
main.c:39:39: warning: format ‘%s’ expects argument of type ‘char ’, but argument 2 has type ‘Element’ {aka ‘struct Element’} [-Wformat=]
39 | printf("Le sommet de la pile est %s,0x%x,%s\n\n",pileSommet(p)); estSommet=1;
| ~^ ~~~~~~
| | |
| char * Element {aka struct Element}
main.c:39:44: warning: format ‘%x’ expects a matching ‘unsigned int’ argument [-Wformat=]
39 | printf("Le sommet de la pile est %s,0x%x,%s\n\n",*pileSommet(p)); estSommet=1;
| ~^
| |
| unsigned int
main.c:39:47: warning: format ‘%s’ expects a matching ‘char ’ argument [-Wformat=]
39 | printf("Le sommet de la pile est %s,0x%x,%s\n\n",pileSommet(p)); estSommet=1;
| ~^
| |
|
L'erreur me dit bien que pileSOmmet() pointe vers Element alors pourquoi n'arrive t'il pas a afficher les elements de la structure ?
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
>
AviateurRex
Modifié le 7 oct. 2021 à 14:34
Modifié le 7 oct. 2021 à 14:34
Parce qu'à chacun des 3 spécificateurs de printf() que tu indiques %s,0x%x,%s doit correspondre un argument passé à la suite d'un type compatible, donc 3 arguments : un chaîne, un entier et une chaîne, et là tu passes 1 seul argument qui est de type struct.
Le compilateur ne sait pas "magiquement" afficher le contenu de la struct, tu dois lui passer le contenu individuel de chaque membre de la struct correspondant au spécificateur d'affichage qui lui correspond.
Le compilateur ne sait pas "magiquement" afficher le contenu de la struct, tu dois lui passer le contenu individuel de chaque membre de la struct correspondant au spécificateur d'affichage qui lui correspond.
AviateurRex
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
7 oct. 2021 à 14:40
7 oct. 2021 à 14:40
c'est à dire qu'il faut que je fasse une sorte de :
en amont dans mon main ?
first_string -> addresse =%s;
value_integer->valeur= 0x%x;
second_string-> chaine="%s;
en amont dans mon main ?
Je ne comprend pas où renseigner les arguments, ça va faire 1H que je cherche mais je n'y arrive pas. Peu importe où je les renseigne dans le printf j'ai toujours une erreur qui suit avec pileSommet().
Comment placer les arguments pour que tout s'affiche donc ? :3
Comment placer les arguments pour que tout s'affiche donc ? :3
[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 7 oct. 2021 à 16:03
Modifié le 7 oct. 2021 à 16:03
Voilà comment tu peux écrire la ligne donnant l'information sur le sommet de la pile en affichant, par exemple, seulement "Fonction#3".
Est-ce que tu arrives à relier les points maintenant ?
Je pense que tu n'as pas (bien) lu les 2 liens vers le tutoriel de ZdS sur les pointeurs et les struct que je t'ai adressés, avec le cas des pointeurs de struct.
Vois : https://zestedesavoir.com/tutoriels/755/le-langage-c-1/1043_aggregats-memoire-et-fichiers/4277_les-pointeurs/
puis : https://zestedesavoir.com/tutoriels/755/le-langage-c-1/1043_aggregats-memoire-et-fichiers/4279_structures/#2-structures-et-pointeurs
Comprendre ces deux chapitres est important pour comprendre pourquoi on fait comme cela. Tu pourrais aussi prendre le tutoriel dès le début et pratiquer chaque chapitre avec des exercices beaucoup plus simples que celui auquel tu t'attaques ... cela ne peut pas faire de mal :-)
printf("\nLe sommet de la pile est %s\n\n", pileSommet(p)->first_string);
Est-ce que tu arrives à relier les points maintenant ?
Je pense que tu n'as pas (bien) lu les 2 liens vers le tutoriel de ZdS sur les pointeurs et les struct que je t'ai adressés, avec le cas des pointeurs de struct.
Vois : https://zestedesavoir.com/tutoriels/755/le-langage-c-1/1043_aggregats-memoire-et-fichiers/4277_les-pointeurs/
puis : https://zestedesavoir.com/tutoriels/755/le-langage-c-1/1043_aggregats-memoire-et-fichiers/4279_structures/#2-structures-et-pointeurs
Comprendre ces deux chapitres est important pour comprendre pourquoi on fait comme cela. Tu pourrais aussi prendre le tutoriel dès le début et pratiquer chaque chapitre avec des exercices beaucoup plus simples que celui auquel tu t'attaques ... cela ne peut pas faire de mal :-)
AviateurRex
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
7 oct. 2021 à 16:26
7 oct. 2021 à 16:26
Depuis le début je laissait le pointeur * sur Pilesommet() ... forcément ça allait avoir du mal à fonctionner x)
Pour l'instant j'ai donc :
Ce qui est carrément bon ! (grâce a 200% à toi) maintenant manque plus que la phase dépilage et c'est fini. Je m'y met de suite.
Pour l'instant j'ai donc :
1.1 Affichage de la pile
Le sommet de la pile est "fonction#3’’, 0x7F543230, ‘’123456’’
|"fonction#3’’, 0x7F543230, ‘’123456’’|
--------------------------------------------------------------
|‘’fonction#2’’, 0x7F543220, ‘’987654’’|
-------------------------------------------------------------
|‘’fonction#1’’, 0x7F543210, ‘’Ok’’ |
------------------------------------------------------------
Ce qui est carrément bon ! (grâce a 200% à toi) maintenant manque plus que la phase dépilage et c'est fini. Je m'y met de suite.
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
>
AviateurRex
7 oct. 2021 à 16:42
7 oct. 2021 à 16:42
pour déréférencer le pointeur sur struct retourné par ta fonction et accéder à un de ses membres, tu peux écrire :
l'opérateur
Le tutoriel de ZdS le dit très clairement :
l’opérateur . s’applique prioritairement à l’opérateur *. (...)
Pour résoudre ce problème, nous devons utiliser des parenthèses afin que l’opérateur . soit appliqué après le déréférencement, ce qui donne la syntaxe suivante.
(*p).heures = 1;
Cette écriture étant un peu lourde, le C fourni un autre opérateur qui combine ces deux opérations : l’opérateur ->.
p->heures = 1;
-
(*pileSommet(p)).first_string
ou alors -
pileSommet(p)->first_string
qui est plus lisible
l'opérateur
->a été créé en C pour signifier les deux actions de déréférencement de pointeur sur struct et d'accès à un membre de la struct, car sinon les règles de préséance des opérateurs
*et
.imposent une syntaxe complexe avec des parenthèses qui est peu commode.
Le tutoriel de ZdS le dit très clairement :
l’opérateur . s’applique prioritairement à l’opérateur *. (...)
Pour résoudre ce problème, nous devons utiliser des parenthèses afin que l’opérateur . soit appliqué après le déréférencement, ce qui donne la syntaxe suivante.
(*p).heures = 1;
Cette écriture étant un peu lourde, le C fourni un autre opérateur qui combine ces deux opérations : l’opérateur ->.
p->heures = 1;
AviateurRex
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
7 oct. 2021 à 16:48
7 oct. 2021 à 16:48
J'avais bien regardé cet exemple justement, dans leur exemple le "p" est définit dans une structure ce qui était différent de mon cas puisque la fonction Pilesommet() était définit par un Elément lui même définit par une structure. C'est pour ça que je n'arrivais pas à faire le parallèle mais finalement c'est le même fonctionnement.
Pour changer je bloque encore xD, bon la fin n'est plus très loin je vais pas arrêter la. Donc, pour dépiler, j'utilise ma fonction pileSupprimer() qui m'enlève -1 à mon compteur d'élément. J'ai donc testé de le mettre à la suite du main simplement après l'exécution de la 1ère phase de la pile ( toujours dans la boucle while donc ) mais ce n'est pas trop concluant. J'arrive bien a dépiler :
Mais je dépile jusqu'à tout supprimer. J'ai donc essayer de rajouter un if a la suite qui aurait comme condition estSommet == 3 avec une suite d'instruction pour dépiler uniquement quand la pile atteint 3 éléments mais la aussi ça ne marche pas
Etat de la pile:
Le sommet de la pile est fonction#3,0x7f543230,123456
|fonction#3,0x7f543230,123456|
------------------------------
2. ON DEPILE UN ELEMENT DE LA PILE
|fonction#2,0x7f543220,987654|
------------------------------
|fonction#2,0x7f543220,987654|
------------------------------
2. ON DEPILE UN ELEMENT DE LA PILE
|fonction#1,0x7f543210,Ok|
------------------------------
|fonction#1,0x7f543210,Ok|
------------------------------
2. ON DEPILE UN ELEMENT DE LA PILE
Mais je dépile jusqu'à tout supprimer. J'ai donc essayer de rajouter un if a la suite qui aurait comme condition estSommet == 3 avec une suite d'instruction pour dépiler uniquement quand la pile atteint 3 éléments mais la aussi ça ne marche pas
[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 7 oct. 2021 à 17:22
Modifié le 7 oct. 2021 à 17:22
Quand tu demandes de l'aide sur un forum, quel qu'il soit :
1. poste ton code
2. indique le résultat que tu obtiens
3. indique le résultat que tu voudrais obtenir
4. explique en quoi ce que tu obtiens te paraît erroné, ce que tu ne comprends pas ou sur quoi tu "bloques" exactement
Notes importantes sur CCM :
c'est plus agréable, et cela permet de te dire, telle ligne tu fais ceci etc.
1. poste ton code
2. indique le résultat que tu obtiens
3. indique le résultat que tu voudrais obtenir
4. explique en quoi ce que tu obtiens te paraît erroné, ce que tu ne comprends pas ou sur quoi tu "bloques" exactement
Notes importantes sur CCM :
- quand tu postes un affichage d'écran, tu peux le faire sur le forum CCM comme tu le fais avec les balises de code simples en cliquant sur bouton code du forum qui insère les balises génériques.
- en revanche, quand tu postes du code dans un certain langage, utilise la flèche ▼ à droite du bouton, et sélectionne le langage (ici "c") pour disposer de balises qui vont correctement colorer syntaxiquement ton code lors de son affichage sur le forum et numéroter les lignes.
c'est plus agréable, et cela permet de te dire, telle ligne tu fais ceci etc.
AviateurRex
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
7 oct. 2021 à 17:33
7 oct. 2021 à 17:33
Désolé pour les balises, je n'avais pas vu qu'on pouvait spécifier le type de langage qu'on utilisait .
Mon main.c:
Mon résultat :
Mon main.c:
#include "pile.h" int main() { printf("1. INITIALISATION DE LA PILE\n"); Pile p; Element *elem; int estSommet=0; p=pileVide(); struct Element el1; el1.first_string="fonction#1"; el1.integer_value=0x7F543210; el1.second_string="Ok"; struct Element el2; el2.first_string="fonction#2"; el2.integer_value=0x7F543220; el2.second_string="987654"; struct Element el3; el3.first_string="fonction#3"; el3.integer_value=0x7F543230; el3.second_string="123456"; pileAjouter(p,el1); pileAjouter(p,el2); pileAjouter(p,el3); printf("\n Etat de la pile:"); [02:31] while(pileLongueur(p)>0){ if(estSommet == 0){ printf("\nLe sommet de la pile est %s,0x%x,%s\n\n", pileSommet(p)->first_string,pileSommet(p)->integer_value,pileSommet(p)->second_string); estSommet=1; } printf( "|%s,0x%x,%s|\n",pileSommet(p)->first_string,pileSommet(p)->integer_value,pileSommet(p)->second_string) ; printf("------------------------------\n"); pileSupprimer(p); printf("2. ON DEPILE UN ELEMENT DE LA PILE\n"); printf( "|%s,0x%x,%s|\n",pileSommet(p)->first_string,pileSommet(p)->integer_value,pileSommet(p)->second_string) ; printf("------------------------------\n"); } return (0);
Mon résultat :
Etat de la pile:
Le sommet de la pile est fonction#3,0x7f543230,123456
|fonction#3,0x7f543230,123456|
------------------------------
2. ON DEPILE UN ELEMENT DE LA PILE
|fonction#2,0x7f543220,987654|
------------------------------
|fonction#2,0x7f543220,987654|
------------------------------
2. ON DEPILE UN ELEMENT DE LA PILE
|fonction#1,0x7f543210,Ok|
------------------------------
|fonction#1,0x7f543210,Ok|
------------------------------
2. ON DEPILE UN ELEMENT DE LA PILE
Le résultat attendu :
La ou je bloque :
Seulement retirer le dernier élément de la pile une seule et unique fois et pas jusqu'à la suppression de la pile.
1.1 Affichage de la pile
Le sommet de la pile est "fonction#3’’, 0x7F543230, ‘’123456’’
|"fonction#3’’, 0x7F543230, ‘’123456’’|
--------------------------------------------------------------
|‘’fonction#2’’, 0x7F543220, ‘’987654’’|
-------------------------------------------------------------
|‘’fonction#1’’, 0x7F543210, ‘’Ok’’ |
------------------------------------------------------------
2 ON DEPILE UN ELEMENT DE LA PILE
Le sommet de la pile est ‘’fonction#2’’, 0x7F543220, ‘’987654’’
|‘’fonction#2’’, 0x7F543220, ‘’987654’’|
------------------------------------------------------------
|‘’fonction#1’’, 0x7F543210, ‘’Ok’’ |
------------------------------------------------------------
La ou je bloque :
Seulement retirer le dernier élément de la pile une seule et unique fois et pas jusqu'à la suppression de la pile.
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
>
AviateurRex
Modifié le 7 oct. 2021 à 17:48
Modifié le 7 oct. 2021 à 17:48
Tu n'as donc pas besoin d'une boucle while.
Edit: je viens de voir ton 2ème message
en fait tu veux pouvoir afficher le contenu de toute la pile sans dépiler ?
cela me semble aller à l'encontre à l'idée de pile ... où par définition tu n'accèdes qu'au sommet ...
Edit: je viens de voir ton 2ème message
en fait tu veux pouvoir afficher le contenu de toute la pile sans dépiler ?
cela me semble aller à l'encontre à l'idée de pile ... où par définition tu n'accèdes qu'au sommet ...
AviateurRex
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
7 oct. 2021 à 17:50
7 oct. 2021 à 17:50
En fait il y a 2 parties si on veut. La partie pour laquelle tu m'as montré comment faire pointer Pilesommet(), donc simplement afficher tous mes éléments et son sommet. Et la seconde partie, qui s'exécute à la suite directement, enlève le dernier élément ajouté (ici el3 ) pour encore afficher la pile mais cette fois avec un nouveau sommet forcément puisqu'on à supprimé el3 qui sera remplacé par el2.
Le résultat attendu :
S'obtient en une seule exécution du code.
Le résultat attendu :
Le sommet de la pile est "fonction#3’’, 0x7F543230, ‘’123456’’
|"fonction#3’’, 0x7F543230, ‘’123456’’|
--------------------------------------------------------------
|‘’fonction#2’’, 0x7F543220, ‘’987654’’|
-------------------------------------------------------------
|‘’fonction#1’’, 0x7F543210, ‘’Ok’’ |
------------------------------------------------------------
2 ON DEPILE UN ELEMENT DE LA PILE
Le sommet de la pile est ‘’fonction#2’’, 0x7F543220, ‘’987654’’
|‘’fonction#2’’, 0x7F543220, ‘’987654’’|
------------------------------------------------------------
|‘’fonction#1’’, 0x7F543210, ‘’Ok’’ |
------------------------------------------------------------
S'obtient en une seule exécution du code.
EDIT
Comme d'habitude je rame mais c'est pas grave x). J'ai essayé plusieurs choses. Tout d'abord je me suis dis que la fonction pileSupprimer() s'exécutait jusqu'à supprimer tous les éléments alors que moi je n'ai besoins qu'elle ne supprime que le sommet de la pile. J'ai donc essayé de rajouter des break pour contraindre le pileSupprimer() à enlever un seul élément.
Avec ce code :
J'obtiens :
1. Initialisation d'une pile
Ce qui revoit du coup les bons sommets mais pas les piles en entières.
Comme d'habitude je rame mais c'est pas grave x). J'ai essayé plusieurs choses. Tout d'abord je me suis dis que la fonction pileSupprimer() s'exécutait jusqu'à supprimer tous les éléments alors que moi je n'ai besoins qu'elle ne supprime que le sommet de la pile. J'ai donc essayé de rajouter des break pour contraindre le pileSupprimer() à enlever un seul élément.
Avec ce code :
while (pileLongueur(p)>0){ if(estSommet == 0){ printf("\nLe sommet de la pile est %s,0x%x,%s\n\n", pileSommet(p)->first_string,pileSommet(p)->integer_value,pileSommet(p)->second_string); estSommet=1; printf( "|%s,0x%x,%s|\n",pileSommet(p)->first_string,pileSommet(p)->integer_value,pileSommet(p)->second_string) ; printf("------------------------------\n"); pileSupprimer(p); printf("2. ON DEPILE UN ELEMENT DE LA PILE\n"); printf("\nLe sommet de la pile est %s,0x%x,%s\n\n", pileSommet(p)->first_string,pileSommet(p)->integer_value,pileSommet(p)->second_string); estSommet=1; printf( "|%s,0x%x,%s|\n",pileSommet(p)->first_string,pileSommet(p)->integer_value,pileSommet(p)->second_string) ; printf("------------------------------\n"); } break;
J'obtiens :
1. Initialisation d'une pile
Le sommet de la pile est "fonction#3’’, 0x7F543230, ‘’123456’’
|"fonction#3’’, 0x7F543230, ‘’123456’’|
--------------------------------------------------------------
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2. ON DEPILE UN ELEMENT DE LA PILE
Le sommet de la pile est ‘’fonction#2’’, 0x7F543220, ‘’987654’’
|‘’fonction#2’’, 0x7F543220, ‘’987654’’|
------------------------------------------------------------
Ce qui revoit du coup les bons sommets mais pas les piles en entières.
EDIT
J'ai réussi à afficher le nombre d'éléments de la pile avec la ligne :
Même si j'ai un avertissement me disant que %i est de type int et pileLongueur(p) est de type int *. Pour pouvoir utiliser pileLongueur j'ai modifié sa structure en tant que
afin de récupérer les informations de la pile.
J'ai réussi à afficher le nombre d'éléments de la pile avec la ligne :
printf("\n Nombre d'élements: %i,pileLongueur(p) );
Même si j'ai un avertissement me disant que %i est de type int et pileLongueur(p) est de type int *. Pour pouvoir utiliser pileLongueur j'ai modifié sa structure en tant que
int *pileLongueur(Pile p)
afin de récupérer les informations de la pile.
[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 8 oct. 2021 à 10:11
Modifié le 8 oct. 2021 à 10:11
Pour pouvoir utiliser pileLongueur j'ai modifié sa structure en tant que
Non, laisse la en
Par ailleurs, le simple fait de changer son prototype (et non sa "structure") ne va pas magiquement faire que la fonction va retourner autre chose que ce qu'elle fait. Tu crées juste une incohérence dans le type de ce qu'elle retourne.
J'ai donc essayé de rajouter des break pour contraindre le pileSupprimer() à enlever un seul élément. Avec ce code :
Après avoir rempli ta pile avec les 3 éléments Ton code d'origine (que tu essayes de bidouiller) fait , en gros :
Alors que, si je comprends bien, ton travail consiste à fournir à l'écran les résultats successifs des appels suivants après avoir rempli ta pile avec les 3 éléments :
C'est juste une séquence d'opérations. Comme je le disais plus haut, tu n'as pas besoin d'un while qui dépile la pile tant qu'elle n'est pas vide, puisque ce n'est pas ce que tu veux faire.
Là pour le coup ce n'est plus un problème de compréhension du langage C, mais d'algorithmique, car tu trouves ce type de boucle dans tous les langages.
Tu n'as pas besoin de ce while, par contre tu as besoin d'une fonction
Relis mon post https://forums.commentcamarche.net/forum/affich-37364731-pile-en-c#41 à partir de "Enfin, si tu dois vraiment afficher le contenu de la pile sans dépiler, tu ne dois pas utiliser un while comme dans ton code qui dépile toute la pile en n'affichant que le sommet à chaque itération." et mes posts suivants.
int *pileLongueur(Pile p)afin de récupérer les informations de la pile.
Non, laisse la en
int pileLongueur(Pile p);, elle retourne un int qui est la seule information qu'il te faut.
Par ailleurs, le simple fait de changer son prototype (et non sa "structure") ne va pas magiquement faire que la fonction va retourner autre chose que ce qu'elle fait. Tu crées juste une incohérence dans le type de ce qu'elle retourne.
J'ai donc essayé de rajouter des break pour contraindre le pileSupprimer() à enlever un seul élément. Avec ce code :
while (pileLongueur(p)>0){(...)
Après avoir rempli ta pile avec les 3 éléments Ton code d'origine (que tu essayes de bidouiller) fait , en gros :
tant que la pile n'est pas vide
pileAfficheSommet(Pile);
pileSupprimer(Pile) ;
fin tant que
Alors que, si je comprends bien, ton travail consiste à fournir à l'écran les résultats successifs des appels suivants après avoir rempli ta pile avec les 3 éléments :
pilelongueur (Pile) ;
pileafficher (Pile) ;
pileSupprimer (Pile) ;
pilelongueur(Pile) ;
pileafficher (Pile) ;
C'est juste une séquence d'opérations. Comme je le disais plus haut, tu n'as pas besoin d'un while qui dépile la pile tant qu'elle n'est pas vide, puisque ce n'est pas ce que tu veux faire.
Là pour le coup ce n'est plus un problème de compréhension du langage C, mais d'algorithmique, car tu trouves ce type de boucle dans tous les langages.
Tu n'as pas besoin de ce while, par contre tu as besoin d'une fonction
void pileAfficher(Pile p);.
Relis mon post https://forums.commentcamarche.net/forum/affich-37364731-pile-en-c#41 à partir de "Enfin, si tu dois vraiment afficher le contenu de la pile sans dépiler, tu ne dois pas utiliser un while comme dans ton code qui dépile toute la pile en n'affichant que le sommet à chaque itération." et mes posts suivants.
AviateurRex
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
8 oct. 2021 à 11:23
8 oct. 2021 à 11:23
Tu as bien compris l'ordre d'execution des fonctions. Je vais enlever le while et voir ce que je peux faire. Lorsqu'on élabore une fonction void celle-ci ne renvoit à rien non ? Je dois L'implémenter dans pile.c à la place de la fonction qui y est déjà ? En attendant je vais déjà essayer de voir la séquence d'empilage/dépilage.
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
>
AviateurRex
Modifié le 8 oct. 2021 à 12:47
Modifié le 8 oct. 2021 à 12:47
Oui, une fonction
Par exemple, tu pourrais décider que ta fonction a un prototype
Je dois L'implémenter dans pile.c à la place de la fonction qui y est déjà ?
A la place de quelle fonction ? Cette fonction ne remplace aucune "qui y est déjà". C'est une fonction nouvelle que tu dois créer car tu ne disposes d'aucune fonction dans ton module te permettant de parcourir le contenu d'une Pile sans dépiler pour afficher ce contenu. Ce dont tu disposes c'est de fonctions permettant de retourner le sommet de la pile et de dépiler.
Que tu la mettes dans ton main.c ou dans ton module, c'est à toi de voir.
Si tu n'es pas l'auteur de ce module, comme je le pense, tu devrais créditer l'auteur de celui-ci et identifier tes changements dans des commentaires.
void pileAfficher(Pile p);ne renvoie rien. Mais c'est à toi de juger si cette proposition te convient.
Par exemple, tu pourrais décider que ta fonction a un prototype
int pileAfficher(Pile p);et renvoie un code d'erreur ou de succès, ou autre chose. Cela ne semble pas pertinent, par contre, de lui faire retourner la Pile p comme les fonctions
Pile pileAjouter(Pile p, Element e);et
Pile pileSupprimer(Pile p);car, contrairement à ces fonctions, la tienne ne vas rien changer au contenu de la Pile.
Je dois L'implémenter dans pile.c à la place de la fonction qui y est déjà ?
A la place de quelle fonction ? Cette fonction ne remplace aucune "qui y est déjà". C'est une fonction nouvelle que tu dois créer car tu ne disposes d'aucune fonction dans ton module te permettant de parcourir le contenu d'une Pile sans dépiler pour afficher ce contenu. Ce dont tu disposes c'est de fonctions permettant de retourner le sommet de la pile et de dépiler.
Que tu la mettes dans ton main.c ou dans ton module, c'est à toi de voir.
Si tu n'es pas l'auteur de ce module, comme je le pense, tu devrais créditer l'auteur de celui-ci et identifier tes changements dans des commentaires.
Si je comprend bien, je dois créer une nouvelle dans ce style là ?
void pileAfficher(Pile p) { if (p== NULL) { exit(EXIT_FAILURE); } Element *actuel = pile->premier; while (actuel != NULL) { printf("%s,0x%x,%s\n", actuel->first_string,actuel->integer_value,actuel->second_string); actuel = actuel->suivant; } printf("\n"); }
EDIT
ça fait un petit moment déjà que je suis sur cette fonction void et je pense être sur la bonne voie.
J'ai la fonction suivante :
Qui me renvoie une erreur et un avertissement :
ça fait un petit moment déjà que je suis sur cette fonction void et je pense être sur la bonne voie.
J'ai la fonction suivante :
void pileAfficher(Pile p){ if(p==NULL) { exit(EXIT_FAILURE); } Element *actuel = p->sommet; while (actuel != NULL) { printf("%s,0x%x,%s\n",actuel->first_string,actuel->integer_value,actuel->second_string); actuel = actuel->psuiv; } printf("\n"); }
Qui me renvoie une erreur et un avertissement :
pile.c: In function ‘pileAfficher’:
pile.c:59:20: warning: initialization of ‘Element *’ {aka ‘struct Element *’} from incompatible pointer type ‘struct SCellule *’ [-Wincompatible-pointer-types]
59 | Element *actuel = p->sommet;
| ^
pile.c:64:18: error: ‘Element’ {aka ‘struct Element’} has no member named ‘psuiv’
64 | actuel = actuel->psuiv;
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
8 oct. 2021 à 17:00
8 oct. 2021 à 17:00
As tu bien lu mon post https://forums.commentcamarche.net/forum/affich-37364731-pile-en-c#41 à partir de "Enfin, si tu dois vraiment afficher le contenu de la pile sans dépiler, tu ne dois pas utiliser un while comme dans ton code qui dépile toute la pile en n'affichant que le sommet à chaque itération." (et mes posts suivants).
Quel est le type de Pile, que contient-il, quel est le type des éléments qu'il contient ?
Tu ne peux pas faire "au hasard, en aveugle".
Quel est le type de Pile, que contient-il, quel est le type des éléments qu'il contient ?
Tu ne peux pas faire "au hasard, en aveugle".
[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
8 oct. 2021 à 17:03
8 oct. 2021 à 17:03
c'est la 3ème fois que je t'alerte sur ces informations. Au bout de 3 fois j'ai atteint mon quota et je ne me répète plus :-)
AviateurRex
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
8 oct. 2021 à 17:13
8 oct. 2021 à 17:13
Je ne veux pas te faire un affront loin de là x).
Le type de Pile est un pointeur vers SPile composé du nombre d'élements et de sommet qui est un pointeur sur SCellule.
Jusqu'ici c'est ça non ?
Le type de Pile est un pointeur vers SPile composé du nombre d'élements et de sommet qui est un pointeur sur SCellule.
Jusqu'ici c'est ça non ?
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
>
AviateurRex
Modifié le 8 oct. 2021 à 17:42
Modifié le 8 oct. 2021 à 17:42
oui, donc, si
Sois rigoureux et remonte le fil des types jusqu'à arriver aux données qui t'intéressent.
Sinon, au temps pour moi, contrairement à ce que j'ai dit dans mon post précédent, il semble que l'implémentation pile.c ne mette pas psuiv à NULL pour la dernière Cellule (ce qui est quand même très usuel pour une liste chaînée, mais bon). Tu dois donc exclusivement te baser sur le nombre d'éléments pour savoir quand tu t'arrêtes, que tu peux obtenir de différentes façons.
Le module n'est pas forcément codé très rigoureusement, mais c'est un truc rapide "qui marche" :-)
Essaye déjà d'accéder aux données du sommet de cette façon, ensuite tente de construire ta boucle qui passe à psuiv tant que le nombre d'éléments te permet de te fier à l'adresse mémoire que tu trouveras dans le pointeur.
p->sommetest un pointeur sur SCellule, tu ne peut par le stocker dans une variable de type Element *
Sois rigoureux et remonte le fil des types jusqu'à arriver aux données qui t'intéressent.
Sinon, au temps pour moi, contrairement à ce que j'ai dit dans mon post précédent, il semble que l'implémentation pile.c ne mette pas psuiv à NULL pour la dernière Cellule (ce qui est quand même très usuel pour une liste chaînée, mais bon). Tu dois donc exclusivement te baser sur le nombre d'éléments pour savoir quand tu t'arrêtes, que tu peux obtenir de différentes façons.
Le module n'est pas forcément codé très rigoureusement, mais c'est un truc rapide "qui marche" :-)
Essaye déjà d'accéder aux données du sommet de cette façon, ensuite tente de construire ta boucle qui passe à psuiv tant que le nombre d'éléments te permet de te fier à l'adresse mémoire que tu trouveras dans le pointeur.
AviateurRex
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
8 oct. 2021 à 17:50
8 oct. 2021 à 17:50
Il y a quelque chose que je ne comprend pas.
Par exemple la ligne ou je définis l'élément actuel :
Je ne peux pas écrire ça puisque actuel est de type Element et sommet de type SCellule. Mais c'est pourtant cette donnée qui m'intéresse non ?
Ecrire :
Serait juste mais ne m'avancerai à rien puisque j'ai besoin que l'élément actuel soit le premier donc le sommet de la pile.
Même soucis pour passer à l'element suivant.
Je pourrai écrire :
Pourtant j'ai besoin de l'élément suivant mais celui ci est aussi de type SCellule.
Par exemple la ligne ou je définis l'élément actuel :
Element *actuel = p->sommet
Je ne peux pas écrire ça puisque actuel est de type Element et sommet de type SCellule. Mais c'est pourtant cette donnée qui m'intéresse non ?
Ecrire :
Element *actuel = p->sommet->info
Serait juste mais ne m'avancerai à rien puisque j'ai besoin que l'élément actuel soit le premier donc le sommet de la pile.
Même soucis pour passer à l'element suivant.
Je pourrai écrire :
actuel = p->sommet->info
Pourtant j'ai besoin de l'élément suivant mais celui ci est aussi de type SCellule.
Je vois vraiment pas comment finir ce void x(. Je t'assure que j'ai passé la journée dessus mais rien. Je dois surement mal réfléchir et mal chercher mais la vraiment je vois pas comment faire.
Je suis obligé de définir mon element "actuel" en le pointant vers Element pour en définir sa structure. Comment accéder à une information, sommet ou psuiv qui sont par nature différente de la nature d'actuel. Et pour la boucle un
Je suis obligé de définir mon element "actuel" en le pointant vers Element pour en définir sa structure. Comment accéder à une information, sommet ou psuiv qui sont par nature différente de la nature d'actuel. Et pour la boucle un
if(estsommet==0)serait correct non ?
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
1 096
8 oct. 2021 à 21:48
8 oct. 2021 à 21:48
Fais les choses progressivement.
La liste d'éléments est, en fait une liste chaînée de Cellules, qui chacune contiennent "info" qui est de type Element et un pointeur vers la Cellule suivante dans la pile.
Vérifie que ton code compile sans erreurs ni avertissements, et que ce que tu écris a un sens avec les types réels de ton module que tu dois manipuler, pas en fonction de ce que tu penses que cela devrait être, mais en fonction de la réalité des types dont tu disposes.
La liste d'éléments est, en fait une liste chaînée de Cellules, qui chacune contiennent "info" qui est de type Element et un pointeur vers la Cellule suivante dans la pile.
Vérifie que ton code compile sans erreurs ni avertissements, et que ce que tu écris a un sens avec les types réels de ton module que tu dois manipuler, pas en fonction de ce que tu penses que cela devrait être, mais en fonction de la réalité des types dont tu disposes.
/* RAPPEL DES TYPES PERTINENTS struct SCellule { Element info; struct SCellule *psuiv; }; typedef struct SCellule *Cellule; struct SPile{ struct SCellule *sommet; int nbElements; }; typedef struct SPile *Pile; Pile */ void pileAfficher(Pile p){ /* comme struct SPile * contient un membre nbElements, je le récupère * pour savoir combien d'éléments je dois afficher */ int nbElements = p->nbElements; /* on traite d'abord des cas d'erreurs ou bien où on ne va rien faire */ if (p==NULL) { exit(EXIT_FAILURE); } if (nbElements < 1) { printf("La pile est vide, rien à afficher\n"); return; } /* arrivé ici, on a quelque chose à afficher */ printf("Affichage des %d élément(s) de la pile :\n", nbElements); /* je récupère la cellule qui est au sommet, un nom court comme c sera * pratique pour la suite ... jusqu'ici rien de difficile, non ? */ struct SCellule * c = p->sommet; /* TODO: à partir de cette cellule (qui est un pointeur sur struct), * accéder au membre info de la cellule, qui est une struct de type * Element, et accéder à ses membres first_string, integer_value et * pour les afficher second_string */ printf("%s,0x%x,%s\n", cXXXXfirst_string, cXXXXinteger_value, cXXXXecond_string); }
AviateurRex
>
[Dal]
Messages postés
6198
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
13 décembre 2024
9 oct. 2021 à 04:27
9 oct. 2021 à 04:27
Okay je comprend mieux l'approche que je dois avoir. Mais la encore la logique m'échappe.
Si j'initialise c comme étant un pointeur sur une struct SCellule, comment recueillir par la suite des infos de type Element ?
écrire :
Si j'initialise c comme étant un pointeur sur une struct SCellule, comment recueillir par la suite des infos de type Element ?
écrire :
c=c->infoest incorrect. J'ai du mal à voir comment organiser des pointeurs pour que 2 éléments qui à la base ont une structure différente puisse "communiquer". Partir de c pour arriver à info c'est bien ça le but non ?
9 oct. 2021 à 18:41
Fais le seulement après avoir fait l'effort de réfléchir par toi même à ce que tu fais et avoir tenté de déboguer ton code, au lieu de poster un truc approximatif toutes les 5 minutes avec une réflexion superficielle.
Je dois m'absenter pendant plusieurs heures.
A toi de jouer.
9 oct. 2021 à 18:49