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
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:

//   	
// 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:

24 réponses

J'ai bien essayé d'appliquer ce qui est sur le site : https://zestedesavoir.com/tutoriels/755/le-langage-c-1/1043_aggregats-memoire-et-fichiers/4279_structures/#2-structures-et-pointeurs

Mais vraiment je trouve rien qui marche.

J'ai essayé de voir comment partir de c pour "atterir" sur les infos de Element mais rien.

printf("%s,0x%x,%s\n", cXXXXfirst_string, cXXXXinteger_value, cXXXXecond_string);
}


Et pour cette ligne là, pourquoi avoir rajouté des "cXXXX" avant chaque membre ?
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
9 oct. 2021 à 16:44
Si j'initialise c comme étant un pointeur sur une struct SCellule, comment recueillir par la suite des infos de type Element ?

Dans une variable de type Element, par exemple.

Dal
0
Donc a la suite je créer une nouvelle variable comme :

struct Element *f=->sommet->info;


par exemple ?

Pourtant tu notifies bien que je dois partir de la variable c pour accèder aux infos non ?
0
J'ai vraiment bloqué toute la journée littéralement x). Je vois pas comment structurer ce que tu dis ici avec la variable c ou la variable c + une variable de type Element :

 /* 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 */
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
9 oct. 2021 à 17:20
écrire :
c = c->info
est incorrect.


Oui c'est incorrect car on vient déclarer c comme étant de type struct SCellule * et c->info est de type Element.

/* 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
*/


Il te faut une variable de type Element pour y ranger un contenu de ce type.

C'est quand même la base, arrête de faire des choses au hasard.
0
Oui je sais bien que c'est impossible d'écrire ça. C'est juste que je voyais pas comment accéder aux infos de type struct en partant de la variable c, comme tu l'as dis c'est en partant de cette cellule qu'on doit accéder à ces informations alors je ne voyais pas comment il fallait que je m'y prenne. Maintenant je sais que j'ai besoin de créer une variable Element comme
struct Element f=p->sommet->info
mais je ne pourrais toujours pas l'utiliser avec c puisque leurs types sont différents.
0
[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 9 oct. 2021 à 18:01
Tu écris :
struct Element f = p->sommet->info;
...

cependant
struct Element
n'est pas un type connu dans ton code, car tu as définit ton type struct sans étiquette à la suite un mot clef struct et en utilisant un alias typedef Element comme suit :

typedef struct {
    char *first_string;
    int integer_value; 
    char *second_string;
} Element;


Par contre, tu peux écrire :
Element f = p->sommet->info;
et récupérer directement ces données.

Vérifie que tu peux accéder aux données des membres.

(au passage pourquoi appeler un élément "f" ... je préfère "el" comme élément ou "e")

Dans mon exemple, je te propose de passer par une variable
struct SCellule  * c
où tu ranges la cellule courante. Le but est de te faciliter la vie pour rendre ton code générique et utiliser cette variable pointeur pour y mettre l'adresse de la cellule suivante quand c'est ce que tu voudras faire...

    /* 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;


qu'est-ce qui t'empêche de créer une variable de type Element pour y ranger le contenu du membre info de c ?
0
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 à 18:00
Pour la création de c, pas de soucis j'ai bien compris ce que tu as fait. Tu fais pointer c vers SCellule pour avoir accès au sommet.


qu'est-ce qui t'empêche de créer une variable de type Element pour y ranger le contenu du membre info de c ?


Je pense que c'est ça que je ne comprends pas, pour l'instant j'ai :

 struct SCellule  * c = p->sommet;
   Element f = p->sommet->info;


Et je dois mettre c dans mon Element f ?
0
[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 9 oct. 2021 à 18:09
Oui, tu peux utiliser c à droite du signe égal après
Element f =
pour accéder au membre info de la cellule, qui est de type Element (cela tombe bien, non ?).

Et tu peux aussi utiliser c pour accéder au membre psuiv qui te servira pour trouver le pointeur vers la cellule suivante.
0
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 à 18:15
J'ai modifié Element f en Element el comme tu l'as dis.

J'ai donc :

 struct SCellule  * c = p->sommet;
 Element el = p->sommet->info;
 Element el=c->info


C'est correct comme ça ?

Et pour le printf() je renseigne les modules comme el.first_string ... ou autrement ?
0