IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

TAD matrice (structure + tableau dynamique)


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné Avatar de supermanu
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    330
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 330
    Par défaut TAD matrice (structure + tableau dynamique)
    salut tout le monde !

    je suis plutôt débutant en C et je dois réaliser une classe matrice en C.

    J'ai trois fichiers :
    matrice.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    typedef struct matrice *matrice;
     
    /* Fonctions */
    matrice initialiserMatriceNulle(int, int);
    matrice initialiserMatrice(int, int);
     
    ///* Procédures */
    void afficherMatrice(matrice);
    matrice.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
     
    #include "matrice.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
     
     
    struct matrice
        {
        int nbLigne;
        int nbColonne;
        float **tableau;
        };
     
     
     
    //* Procédures */
    //* afficherMatrice(matrice) : Cette procédure affiche une matrice */
    void afficherMatrice(matrice m)
    {
        int i,j;
        for(i=0;i<m->nbLigne;i++)
            {
            for(j=0;j<m->nbColonne;j++)
                {
                printf("\t %lf ",m->tableau[i][j]);
                }    
            printf("\n");
            }    
    }
     
    //* Fonctions */
    matrice initialiserMatriceNulle(int m, int n)
    {
        matrice maMatrice;
        maMatrice = (matrice)malloc(sizeof(struct matrice));
        maMatrice->nbLigne = m;
        maMatrice->nbColonne = n;
     
        maMatrice->tableau = malloc(m*sizeof(*(maMatrice->tableau)));
     
        int i,j;
     
        for(i=0;i<m;i++) 
            maMatrice->tableau[i] = malloc(n*sizeof(**(maMatrice->tableau))); 
     
       for(i=0;i<m;i++) 
          for(j=0;j<n;j++) 
                maMatrice->tableau[i][j]= 4;
     
        return maMatrice;
    }
     
    matrice initialiserMatrice(int m, int n)
    {
        matrice maMatrice = initialiserMatriceNulle(m,n);
        int i,j;
     
        /* m et n doivent être testés avant > 0 et < NMAX */
     
        for(i=0;i<m;i++)
            {
            printf("\nLigne %d :\n",i+1);
            for(j=0;j<n;j++)
                    {
                    printf("\nElement a[%d][%d] = ",i+1,j+1);
                    scanf("%lf",&maMatrice->tableau[i][j]);
                    }
            }        
        return maMatrice;
    }

    main.c (pour tester)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    #include "matrice.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
     
    main()
    {
      int m,n;
      matrice maMatrice,m1,m2;
      printf("Nombre de lignes : ");
      scanf("%d",&m);
      printf("\nNombre de colonnes : ");
      scanf("%d",&n);
     
      maMatrice = initialiserMatriceNulle(m, n);
      afficherMatrice(maMatrice);
     
          m1 = initialiserMatrice(m, n);
      afficherMatrice(m1);
     
    system("PAUSE");	
      return 0;
    }
    : Il m'est imposé de mettre la structure dans matrice.c et de créer un pointeur vers cette structure dans le .h. Ce serait pour "cacher" comment je code une matrice. Quelqu"un pourrait-il m'apporter des infos à ce sujet ? merci.

    : La fonction initialiserMatriceNulle semble marcher. (j'ai mis 4 pour voir si ça affichait bien 4). Par contre la fonction initialiserMatrice me donne une matrice de bonne dimension mais avec que des 0 (même pas des 4). J'ai dû oublier un truc élémentaire ?

    : Avant de quitter le programme, je dois libérer la mémoire ? Je ne peux pas faire seulement un free(matrice) ? il faut que je désalloue toutes les cases. C'est à ce moment là que je crie ausssssssseeeeeeeecccccourrrrrrrssss je suis perdu !

    Voilà ça fait beaucoup de questions. Je tiens à préciser que je travaille avec dev c++ et que j'ai déjà regardé la faq et quelques sujets pour faire mes allocations mémoires, mais avec la structure ça complique les choses...

    Si quelqu'un peu répondre à une des trois questions... hésitez pas !
    Merci

    Manu

  2. #2
    Membre éclairé Avatar de gelam
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2003
    Messages : 69
    Par défaut
    Bonjour,
    Ton code est étrange car tu parles de classes et de langages C. Les classes sont un des "plus" de C++ par rapport au C.
    1)
    Un élément de la qualité logicielle est le masquage de l'information (ce qu'on ne sait pas ne peut pas nuire) d'où le fait de t'imposer la déclaration d'un pointeur dans ton interface. La structure restera cachée dans dans l'implémentation (.c)

    2) et 3)
    Dans ton cas tu désire un tableau à deux dimensions. Les deux dimensions sont dynamiques. Le principe est le suivant :
    Création d'un tableau dynamique à une dimension représentant les lignes de ta matrice. Chaque case de ce tableau (float*) est elle-même un tableau dynamique de float.
    Tu dois dont faire une première allocation pour obtenir ton tableau de lignes, puis pour chaque ligne faire une allocation pour obtenir les éléments de la ligne. Donc si tu as une matrice de 3 lignes et 5 colonnes tu vas devoir faire 4 allocations (malloc).
    Pour liberer la mémoire et par soucis de symétrie (la symétrie c'est esthétique) tu devras donc faire 4 libérations (free).

    Que la force soit avec toi

  3. #3
    Membre chevronné Avatar de Pierre Maurette
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 283
    Par défaut
    Salut supermanu (on dirait du Margerin !)

    D'abord bravo de poster un code "propre" et compilable, ça donne envie d'essayer d'aider.

    Je vais au plus vite pour vous débloquer.
    Remplacez tous les %lf par %f dans les chaînes de format (ou utilisez des double dans la matrice). L'erreur n'est pas gênante dans les printf() mais elle l'est logiquement dans les scanf().
    Faites précéder tous les scanf() par la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while(fgetc(stdin) != '\n');
    Voyez les critiques de scanf() sur Google, les FAQ C. Voyez fr.comp.lang.c, par exemple un fil "printf et scanf" initialisé par Pascal le 2/11/2004 à 19h52.

    A +

    Pierre

  4. #4
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut Re: Classe matrice (structure + tableau dynamique)
    Citation Envoyé par supermanu
    je suis plutôt débutant en C et je dois réaliser une classe matrice en C.
    Si ton prof parle de 'classe' en C, change d'école et fait toi rembourser. Il n'y a pas de 'classe' en C. Par contre, ce que je vois de la suite s'apparente à un TAD (Type Abstrait de Donnée ou ADT, Abstract Data Type), ce qui est la forme la plus basique de l'approche objet en C.

    http://emmanuel-delahaye.developpez.com/tad.htm

    et, après lecture rapide du code, c'est plutôt une bonne approche, alors attend un peu avant de quitter l'école!

    : Il m'est imposé de mettre la structure dans matrice.c et de créer un pointeur vers cette structure dans le .h. Ce serait pour "cacher" comment je code une matrice. Quelqu"un pourrait-il m'apporter des infos à ce sujet ? merci.
    Oui, c'est le principe même du type abstrait de données. La définition de la structure est 'coupée en deux'.

    La partie visible (interface) est réduite à sa plus simple expression:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef struct type type_s;
    ou (dans ton cas)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef struct type *ptype_s;
    alors que dans la partie implémentation, on trouve la définition complète de la structure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct type
    {
       /* liste des elements */
       ...
    };
    : La fonction initialiserMatriceNulle semble marcher. (j'ai mis 4 pour voir si ça affichait bien 4). Par contre la fonction initialiserMatrice me donne une matrice de bonne dimension mais avec que des 0 (même pas des 4). J'ai dû oublier un truc élémentaire ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
             scanf ("%lf", &maMatrice->tableau[i][j]);
    Le type de l'adresse est (float*), alors que type attendu par "%lf" est (double *) Il faut etre coherent.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
             scanf ("%f", &maMatrice->tableau[i][j]);
    D'autre part, d'une façon générale, il faut tester le code retour des fonctions d'entrées (ici, si on a pas 1, c'est qu'il y a une erreur); et il est déconseillé d'utiliser les fonctions scanf() et fscanf() qui sont difficiles, même pour un programmeur expérimenté. Il y a des aletrnatives simples et fiables.

    http://emmanuel-delahaye.developpez....tes.htm#saisie

    : Avant de quitter le programme, je dois libérer la mémoire ? Je ne peux pas faire seulement un free(matrice) ? il faut que je désalloue toutes les cases. C'est à ce moment là que je crie au secours je suis perdu !
    Il suffit de faire le travail inverse.

    - parcourir le tableau de pointeurs pour libérer les blocs un à un
    - libérer le tableau de pointeurs.

    Autres points concernants ton code
    • Les commentaires sont bizarres. C'est soit /* */ (portable), soit // (C99), mais pas un mélange des deux (ça trouble ma machine à relooker les commentaires! )
    • Ton indentation est moche (je sais, c'est une affaire de gout).
    • Plus sérieux, le fichier d'en-tête devrait être encadré par des protections anti inclusions multiples.
      http://emmanuel-delahaye.developpez....ganiser_source
    • Je ne suis pas trop d'accord pour pousser l'abstraction au point de cacher le fait que l'objet est un pointeur. Ca ne facilite pas la relecture du code. Les programmeurs C n'ont pas honte d'utiliser des pointeurs. Il n'y a rien à cacher. Si c'est imposé, je conseille alors de mettre un 'p' dans l'identificateur.
    • Il est inutile de mettre un cast avec malloc()
      http://emmanuel-delahaye.developpez....tes.htm#malloc
    • Contrairement au Pascal, il n'y a pas de 'procedure' en C. Uniquement des fonctions, quelque soit le type retourné.
    • Le nom 'initialiserMatriceNulle()' est mal choisi. Le rôle principal de cette fonction est la création de la matrice (il manque d'ailleurs une fonction de destruction). Je les aurais appelées 'creerMatrice()' et detruireMatrice()'. Pour remplir la matrice de '4', j'aurais crée une fonction de remplissage séparée remplirMatrice() avec la valeur en paramètre. Mais pour vérifier sa matrice, il vaut mieux la remplir de valeurs différentes....
    • Il est assez troublant et étrange qu'il y ait 2 fonctions publiques qui servent à créer l'objet (initialiserMatriceNulle() et initialiserMatrice()). En tant qu'utilisateur, je me demande laquelle il faut utiliser..

    Je n'ai pas étudié ton code dans le détail...

    A l'exécution (après correction du scanf() et instrumentation de la mémoire), j'obtiens ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    D:\DEV-CPP>bc proj.prj
    SYSALLOC BC++ Ver 4.10 LARGE 62096 MS-DOS
    SYSALLOC Overload (14 rec)
    SYSALLOC Successful initialization: 14 records available
    Nombre de lignes : 2
     
    Nombre de colonnes : 3
             4.000000        4.000000        4.000000
             4.000000        4.000000        4.000000
     
    Ligne 1 :
     
    Element a[1][1] = 1.1
     
    Element a[1][2] = 1.2
     
    Element a[1][3] = 1.3
     
    Ligne 2 :
     
    Element a[2][1] = 2.1
     
    Element a[2][2] = 2.2
     
    Element a[2][3] = 2.3
             1.100000        1.200000        1.300000
             2.100000        2.200000        2.300000
    SYSALLOC min=61968 max=62096 delta=128
    SYSALLOC Err: Not-matched list:
    SYSALLOC Bloc 90D6:0004 (8 bytes) malloc'ed at line 36 of 'MATRICE.C' not freed
    SYSALLOC Bloc 90D7:0004 (8 bytes) malloc'ed at line 40 of 'MATRICE.C' not freed
    SYSALLOC Bloc 90D8:0004 (12 bytes) malloc'ed at line 46 of 'MATRICE.C' not freed
     
    SYSALLOC Bloc 90D9:0004 (12 bytes) malloc'ed at line 46 of 'MATRICE.C' not freed
     
    SYSALLOC Bloc 90DA:0004 (8 bytes) malloc'ed at line 36 of 'MATRICE.C' not freed
    SYSALLOC Bloc 90DB:0004 (8 bytes) malloc'ed at line 40 of 'MATRICE.C' not freed
    SYSALLOC Bloc 90DC:0004 (12 bytes) malloc'ed at line 46 of 'MATRICE.C' not freed
     
    SYSALLOC Bloc 90DD:0004 (12 bytes) malloc'ed at line 46 of 'MATRICE.C' not freed
     
    SYSALLOC Err: Memory leak (128 bytes)
    ce qui montre un fonctionnement apparement correct, mais un sérieux problème de libération mémoire, comme tu l'avais évoqué.

    Voici une solution plus... industrielle, disons (avec des appels à ma bibliothèque) :
    http://emmanuel-delahaye.developpez.com/clib.htm
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    #ifndef H_ED_MATRICE_20041113095110
    #define H_ED_MATRICE_20041113095110
     
    #ifdef __cplusplus
    extern "C"
    {
    #endif
     
    /* matrice.h */
     
    /* macros ============================================================== */
    /* constants =========================================================== */
    /* types =============================================================== */
     
       typedef struct matrice matrice_s;
     
    /* structures ========================================================== */
    /* internal public functions =========================================== */
    /* entry points ======================================================== */
     
       matrice_s *matriceCreer (int lin, int col);
       void matriceDetruire (matrice_s *maMatrice);
     
       int matriceAfficher (matrice_s const *self);
       int matriceSaisir (matrice_s *self);
       int matriceRemplir (matrice_s const *self, double value);
     
    /* public variables ==================================================== */
     
    #ifdef __cplusplus
    }
    #endif
     
    #endif                          /* guard */
     
    /* Guards added by GUARD (c) ED 2000-2003 May 09 2004 Ver. 1.6 */
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
     
    /* matrice.c */
    #include "matrice.h"
     
    #include "ed/inc/sysalloc.h"
    #include "ed/inc/io.h"
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
     
    /* macros ============================================================== */
    /* constants =========================================================== */
    /* types =============================================================== */
    /* structures ========================================================== */
     
    struct matrice
    {
       int nbLigne;
       int nbColonne;
       float **tableau;
    };
     
    /* private variables =================================================== */
    /* private functions =================================================== */
    /* internal public functions =========================================== */
    /* entry points ======================================================== */
     
    matrice_s *matriceCreer (int const lin, int const col)
    {
       matrice_s *this = NULL;
     
       if (lin > 0 && col > 0)
       {
          /* creer l'objet */
          this = malloc (sizeof *this);
     
          if (this != NULL)
          {
             /* initialiser l'objet */
             {
                static const matrice_s z =
                {0};
                *this = z;
             }
     
             /* creer le tableau de 'lin' pointeurs 
              * (pas tres optimise, mais simple et sur)
              */
             {
                float **pp = malloc (sizeof *pp * lin);
     
                if (pp != NULL)
                {
                   int i;
                   int err = 0;
     
                   /* initialiser le tableau */
                   for (i = 0; i < lin; i++)
                   {
                      pp[i] = NULL;
                   }
     
                   /* creer les lignes */
                   for (i = 0; i < lin; i++)
                   {
                      float *p = malloc (sizeof *p * col);
     
                      if (p != NULL)
                      {
                         /* effacer la ligne */
                         int j;
     
                         for (j = 0; j < col; j++)
                         {
                            p[j] = 0;
                         }
     
                         pp[i] = p;
                      }
                      else
                      {
                         err = 1;
                         break;
                      }
                   }
     
                   /* erreur memoire ? */
                   if (!err)
                   {
                      this->nbColonne = col;
                      this->nbLigne = lin;
                      this->tableau = pp;
                   }
                   else
                   {
                      matriceDetruire (this), this = NULL;
                   }
                }
             }
          }
       }
       return this;
    }
     
    void matriceDetruire (matrice_s * this)
    {
       if (this != NULL)
       {
          int i;
     
          /* liberer les lignes */
          for (i = 0; i < this->nbLigne; i++)
          {
             free (this->tableau[i]), this->tableau[i] = NULL;
          }
     
          /* liberer le tableau */
          free (this->tableau);
     
          /* liberer l'objet */
          free (this);
       }
    }
     
    int matriceAfficher (matrice_s const *this)
    {
       int err = 0;
     
       if (this != NULL)
       {
          int i;
     
          for (i = 0; i < this->nbLigne; i++)
          {
             int j;
     
             for (j = 0; j < this->nbColonne; j++)
             {
                printf ("%8.2f", this->tableau[i][j]);
             }
             printf ("\n");
          }
       }
       else
       {
          err = 1;
       }
       return err;
    }
     
    int matriceRemplir (matrice_s const *this, double value)
    {
       int err = 0;
     
       if (this != NULL)
       {
          int i;
     
          for (i = 0; i < this->nbLigne; i++)
          {
             int j;
     
             for (j = 0; j < this->nbColonne; j++)
             {
                this->tableau[i][j] = value;
             }
          }
       }
       else
       {
          err = 1;
       }
       return err;
    }
     
    int matriceSaisir (matrice_s * this)
    {
       int err = 0;
     
       if (this != NULL)
       {
          int i;
     
          for (i = 0; i < this->nbLigne; i++)
          {
             int j;
     
             printf ("\nLigne %d :\n", i + 1);
     
             for (j = 0; j < this->nbColonne; j++)
             {
                double value;
     
                printf ("\nElement a[%d][%d] = ", i + 1, j + 1);
     
                get_d (&value);
                /* des controles sont possibles ici... */
                this->tableau[i][j] = value;
             }
          }
       }
       else
       {
          err = 1;
       }
       return err;
    }
     
    /* public variables ==================================================== */
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    /* main.c */
    #include "ed/inc/sysalloc.h"
    #include "ed/inc/io.h"
     
    #include "matrice.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
     
    int main_ (void)
    {
       int lin, col;
       long l;
       matrice_s *maMatrice;
       printf ("Nombre de lignes : ");
       get_l (&l);
       lin = (int) l;
       printf ("\nNombre de colonnes : ");
       get_l (&l);
       col = (int) l;
     
       maMatrice = matriceCreer (lin, col);
     
       matriceRemplir (maMatrice, 4);
       matriceAfficher (maMatrice);
     
       matriceSaisir (maMatrice);
       matriceAfficher (maMatrice);
     
       matriceDetruire (maMatrice);
     
       system ("PAUSE");
       return 0;
    }
     
     
    int main (void)
    {
       int ret;
       static char Trace[1 << 8];
     
       SYS_INIT (Trace, OFF);
     
       ret = main_();
     
       sys_mem_trace();
     
       return ret;
    }

  5. #5
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Pierre Maurette
    Faites précéder tous les scanf() par la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while(fgetc(stdin) != '\n');
    Pourquoi précéder ? C'est scanf() qui ne fait pas le ménage en quittant, c'est donc après scanf() qu'il faut passer l'aspirateur.

  6. #6
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Par défaut
    Ou peut-être tout simplement, ne pas utiliser scanf ?
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  7. #7
    Membre chevronné Avatar de supermanu
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    330
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 330
    Par défaut
    Merci beaucoup pour tous ces commentaires et critiques très constructives !!!!!

    J'ai essayé de prendre point par point ce qui n'allait pas, et j'ai relooké mon code (même si une solution complète m' a été proposée. merciiiiiii !!!! mais je préfèrais essayer par moi même, c com ça qu'on apprend mieux je pense )

    donc voici mes nouvelles sources pour ce TAD matrice :

    matrice.h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #ifndef H_MATRICE
    #define H_MATRICE
     
    /* matrice.h */
     
    /* types ==================================== */
    typedef struct matrice *pmatrice_s;
     
    /* entry points ============================= */ 
    pmatrice_s creerMatrice(int , int);
    void detruireMatriceMatrice(pmatrice_s);
    void afficherMatrice(pmatrice_s);
    #endif
    matrice.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
     
    #include "matrice.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
     
    /* matrice.c */
     
    /* structures ========================================================== */
    struct matrice
        {
        int nbLigne;
        int nbColonne;
        float **tableau;
        };
     
     
    /* internal public functions =========================================== */
     
    pmatrice_s creerMatrice(int m, int n)
    {
        int i,j;
        int ret;
        char temp[20];
        pmatrice_s pMaMatrice;
     
        pMaMatrice = malloc(sizeof(struct matrice));
        pMaMatrice->nbLigne = m;
        pMaMatrice->nbColonne = n;
     
        pMaMatrice->tableau = malloc(m*sizeof(*(pMaMatrice->tableau)));
     
        for(i=0;i<m;i++) 
            pMaMatrice->tableau[i] = malloc(n*sizeof(**(pMaMatrice->tableau)));     
     
        for(i=0;i<m;i++)
            {
            printf("\nLigne %d :\n",i+1);
            for(j=0;j<n;j++)
                    {
                    do
                      {
                      char saisie[20];
                      printf("\nElement a[%d][%d] = ",i+1,j+1);
                      fflush (stdout);
     
                      fgets (saisie, sizeof saisie, stdin);
     
                      ret = sscanf (saisie, "%[0-9-.]s", temp);
                      }
                      while (ret != 1);
     
                      {
                      pMaMatrice->tableau[i][j] = strtof (temp, NULL);
                      }
                    }
            }        
        return pMaMatrice;
    }
     
    void detruireMatrice(pmatrice_s pMaMatrice)
    {
        int i; 
     
        for(i=0;i<pMaMatrice->nbLigne;i++) 
            free(pMaMatrice->tableau[i]); 
        free(pMaMatrice->tableau);   
        free(pMaMatrice);
    }
     
    void afficherMatrice(pmatrice_s pMaMatrice)
    {
        int i,j;
        printf("#\n# La matrice a %d lignes et %d colonnes.\n#\n# ",pMaMatrice->nbLigne,pMaMatrice->nbColonne);
     
     
        for(i=0;i<pMaMatrice->nbLigne;i++)
            {
            for(j=0;j<pMaMatrice->nbColonne;j++)
                {
                printf("\t %f ",pMaMatrice->tableau[i][j]);
                }    
            printf("\n ");
            }    
    }

    main.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    #include "matrice.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
     
    main()
    {
      int m,n;
      pmatrice_s maMatrice,m1,m2;
      printf("Nombre de lignes : ");
      scanf("%d",&m);
      printf("\nNombre de colonnes : ");
      scanf("%d",&n);
     
      maMatrice = creerMatrice(m, n);
      afficherMatrice(maMatrice);
      detruireMatrice(maMatrice);
     
    system("PAUSE");	
    return 0;
    }
    J'ai zappé le point "indentation" mais je pense y revenir...

    : Quand je rentre ma matrice, il m'affiche deux fois Element a[1][1]. Juste pour la première case. Je peux répondre après et ça marche. Mais je vois pas d'où vient ce bug d'affichage ?

    : Ma fonction detruireMatrice, détruit-elle bien la matrice ?

    Je dois encore m'assurer qu'à chaque fois que j'utilise malloc, celà ne me renvoie pas un pointeur NULL.

    mais au final, le programme à l'air de marcher, je voudrais juste être sûr que je ne fais pas de bêtises avec la mémoire !

    encore merci tout le monde !!
    @+

    Manu

  8. #8
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par supermanu
    J'ai zappé le point "indentation" mais je pense y revenir...
    http://freeware.sgi.com/fw-5.3/fw_GNUindent/GNUindent.html
    : Quand je rentre ma matrice, il m'affiche deux fois Element a[1][1]. Juste pour la première case. Je peux répondre après et ça marche. Mais je vois pas d'où vient ce bug d'affichage ?

    : Ma fonction detruireMatrice, détruit-elle bien la matrice ?
    Oui
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    D:\DEV-CPP>bc proj.prj
    SYSALLOC BC++ Ver 4.10 LARGE 62448 MS-DOS
    SYSALLOC Overload (14 rec)
    SYSALLOC Successful initialization: 14 records available
    Nombre de lignes : 2
     
    Nombre de colonnes : 3
     
    Ligne 1 :
     
    Element a[1][1] =
    Element a[1][1] = 1.1
     
    Element a[1][2] = 1.2
     
    Element a[1][3] = 1.3
     
    Ligne 2 :
     
    Element a[2][1] = 2.1
     
    Element a[2][2] = 2.2
     
    Element a[2][3] = 2.3
    #
    # La matrice a 2 lignes et 3 colonnes.
    #
    #        1.100000        1.200000        1.300000
             2.100000        2.200000        2.300000
     SYSALLOC min=62384 max=62448 delta=64
    SYSALLOC All-matched
    SYSALLOC Released Memory
    Coté memoire, ça va. Reste le problème de la ligne doublée...

    C'est dû à l'utilisation de scanf() dans main(). Comme il a été signalé, scanf() laisse trainer un '\n'. Celui-ci est lu par le fgets(), mais comme la conversion est fausse (sscanf() ne renvoi pas 1), la boucle do-while fait un tour de plus.

    Pour corriger, il faut soit ne pas utiliser scanf(), soit vider stdin après usage comme déjà indiqué.

  9. #9
    Membre chevronné Avatar de supermanu
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    330
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 330
    Par défaut
    Merci !!

    - merci pour le lien !
    - merci pour la vérification !

    pour le bug d'affichage, je vais essayer quelques trucs, mais ce n'était pas mon principal problème !

    je vais de ce pas mettre le tag résolu
    encore merci
    @+

    Manu

  10. #10
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par supermanu
    pour le bug d'affichage, je vais essayer quelques trucs, mais ce n'était pas mon principal problème !
    Ce n'est pas un bug d'affichage, mais un bug fonctionnel. Il doit être corrigé.

  11. #11
    Membre chevronné Avatar de supermanu
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    330
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 330
    Par défaut
    C'est bon, c'est corrigé !

    j'ai mis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    while(fgetc(stdin) != '\n');
    après chaque scanf(), et ça marche nickel !!

    merci bcp !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. désallocation mémoire - fonction - structure - tableau dynamique
    Par Flaherty Mc Coillean dans le forum Débuter
    Réponses: 2
    Dernier message: 25/11/2009, 17h42
  2. Structure d'un tableau dynamique
    Par boon31 dans le forum Langage
    Réponses: 7
    Dernier message: 04/11/2007, 20h24
  3. tableau dynamique provenant d'une structure
    Par VenomX dans le forum C
    Réponses: 4
    Dernier message: 17/07/2007, 10h47
  4. Réponses: 4
    Dernier message: 23/03/2007, 09h40
  5. Tableau dynamique de structures
    Par beb30 dans le forum C
    Réponses: 13
    Dernier message: 29/04/2006, 12h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo