Programme avec les piles

Résolu/Fermé
marie12_2000 Messages postés 27 Date d'inscription vendredi 22 mars 2019 Statut Membre Dernière intervention 29 février 2020 - Modifié le 8 avril 2019 à 13:49
marie12_2000 Messages postés 27 Date d'inscription vendredi 22 mars 2019 Statut Membre Dernière intervention 29 février 2020 - 9 avril 2019 à 12:41
Bonjour, le programme ci-dessous ne veut pas marcher. A vrai dire je ne sais pas quand est ce que je dois mettre l’étoile et quand est ce que je dois l'enlever(c'est mon tout premier programme avec les piles), prière de m'aider!

#include <stdio.h>
#include <stdlib.h>
#define MAX 5

typedef struct typepile typepile;
struct typepile
{
    int sommet;
    int tab[MAX];
};
typepile *P;
void creer_pile(typepile *P)
{
    P->sommet=-1;
}

int pile_vide(typepile P)
{
    return (P.sommet==-1);
}

int pile_pleine(typepile P)
{
    return (P.sommet==(MAX-1));
}

int empiler(typepile *P,int x)
{
    if (pile_pleine(*P))
    return 0;
    else
    {
         P->sommet++;
        P->tab[(P->sommet)]=x;
        return 1;
    }
}
int depiler(typepile *P,int *x)
{
    if(pile_vide(*P))
       return 0;
    else
    {
      *x=P->tab[P->sommet];
      P->sommet--;
      return 1;
    }
}
int main()
{    int a,i;
    typepile *P;
    creer_pile(P);
    a=empiler(P,9);
    if(a==0)
        printf("la pile est pleine\n");
    a=empiler(P,8);
     if(a==0)
        printf("la pile est pleine\n");
     a=empiler(P,7);
     if(a==0)
        printf("la pile est pleine\n");
    a=empiler(P,6);
     if(a==0)
        printf("la pile est pleine\n");
     a=empiler(P,5);
     if(a==0)
        printf("la pile est pleine\n");
        for(i=0;i<MAX;i++)
            printf("%d\n",P->tab[i]);
    return 0;
}

1 réponse

[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
Modifié le 8 avril 2019 à 15:16
Salut marie12_2000,

Je n'ai pas testé ton code, mais voilà quelques remarques.

1.

En ligne 11 tu déclares une variable globale
typepile *P;
dont tu ne te sers pas. Tu devrais la supprimer.

2.

Tes prototypes de fonctions devraient toujours prévoir le passage d'un pointeur sur la
struct
, même si la pile n'a pas à être modifiée et que tu testes juste si la pile est vide ou pleine.

La raison est que, autrement, l'appel à la fonction fera une copie de la
struct
qui peut contenir de nombreux éléments (là il en a 5, mais imagine une structure de données beaucoup plus grande), cette copie va prendre du temps processeur et va utiliser de la mémoire inutilement.

3.

Dans ton main, tu déclares en ligne 52
typepile *P;
, c'est à dire un pointeur sur ta
struct
, mais tu n'alloues pas la mémoire nécessaire au stockage du contenu pointé, et tout ce que tu as c'est une variable pointeur pouvant juste contenir une adresse mémoire (non initialisée d'ailleurs et qui peut donc contenir n'importe quoi). C'est probablement le problème le plus visible à l'exécution : le programme doit planter, car tu tentes d'écrire et de lire en mémoire à des emplacements non alloués au programme.

Pour stocker le contenu de ta
struct
, il te faut un espace mémoire auquel le programme a accès.

Le plus simple est de déclarer
typepile P;
et de passer aux fonctions
&P
pour passer l'adresse de la
struct
pour satisfaire les prototypes des fonctions, qui devraient attendre un pointeur sur la
struct
pour les raisons expliquées ci-avant.


Dal
1
marie12_2000 Messages postés 27 Date d'inscription vendredi 22 mars 2019 Statut Membre Dernière intervention 29 février 2020
8 avril 2019 à 18:14
merci dal ca marche mais j'aimerai savoir pourquoi on ne met pas
*P->sommet
a la place de
P->sommet
?
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
Modifié le 9 avril 2019 à 09:51
P->sommet
et
(*P).sommet
ont le même sens (note les parenthèses et le point).

Ils utilisent
P
comme un pointeur sur une
struct
, déréférencent ce pointeur, et accèdent au membre
sommet
de la
struct
ainsi pointée.

La notation
P->
est juste un raccourci plus pratique que d'avoir à ouvrir une parenthèse, utiliser l'opérateur d'indirection
*
écrire le nom de la variable pointeur, fermer la parenthèse et utiliser l'opérateur
.
pour l'accès au membre de la
struct
.

Ce raccourci est pratique, car il très fréquent en C de devoir utiliser des pointeurs sur
struct
pour accéder indirectement aux membres, et cela donne un code plus lisible, sans parenthèses. Les parenthèses seraient nécessaires sans l'opérateur
->
en raison de la préséance des opérateurs en C : https://en.cppreference.com/w/c/language/operator_precedence

Si tu écris
*P->sommet
, tu écris autre chose en raison de la préséance des opérateurs en C : l'opérateur
->
est prioritaire sur l'opérateur d'indirection
*
et ce code signifierait :

- que tu accèdes au contenu du membre
sommet
d'une
struct
en déréférençant le pointeur
P
avec l'opérateur
->
,
- et que tu traites le contenu du membre
sommet
comme une adresse mémoire, puisque tu tentes de le déréférencer avec l'opérateur
*
...

Cela n'a pas de sens dans ton code, puisque
sommet
n'est pas lui même un pointeur, mais un
int
.
0
marie12_2000 Messages postés 27 Date d'inscription vendredi 22 mars 2019 Statut Membre Dernière intervention 29 février 2020
9 avril 2019 à 12:41
super bonne explication! merci!
0