Partage
  • Partager sur Facebook
  • Partager sur Twitter

Encore une question sur les structures

    16 juin 2006 à 10:41:36

    Je suis en train de commence un jeu, et pour l'affichage de l'univers j'ai repris le principe d'un tableau à 2 dimention comme pour le mario sokoban. Pour organiser mon code je veut creer un structure elle devrait resembler à ca
    struct affichage
      {
      int largeur; //nombre de case en largeur (cette variable varie dans l'interval [300;500] )
      int hauteur; //nombre de case en hauteur
      int *tableau //Je veut creer le tableau a 2 dimention ici, mais je veut le faire dynamiquement
      ...
      };

    Mon probleme c'est est ce que j'ai le droit de mettre un pointeur dans une structure si oui comme j'y accede, ensuite pour l'alloc dynamique c'est pas bien compliqué
    • Partager sur Facebook
    • Partager sur Twitter
      16 juin 2006 à 10:57:45

      Normalement tu peux !
      Pour accéder à ton pointeur du fait affichage.tableau ;
      pour accéder à la valeur sur laquelle tableau pointe ce sera affichage.(*tableau) ! (à vérifier mais ce que la logique indique !)
      • Partager sur Facebook
      • Partager sur Twitter
        16 juin 2006 à 11:19:41

        j'ai donc testé et ben ca veut pas compiler, le code c'est:
        #include <stdio.h>
        #include <stdlib.h>


        typedef struct Affichage Affichage;
        struct Affichage
          {
          int largeur; //nombre de case en largeur (cette variable varie dans l'interval [300;500] )
          int hauteur; //nombre de case en hauteur
          int *tableau; //Je veut creer le tableau a 2 dimention ici, mais je veut le faire dynamiquement
          };

        int main(int argc, char *argv[])
        {
          Affichage var;
         
          var.largeur = 100;
          var.hauteur = 20;
          var.tableau = malloc(sizeof(int) * var.largeur * var.hauteur);
          if(var.tableau == NULL)
            exit(EXIT_FAILURE);
         
          var.tableau[10][88] = 10;
          printf("%d",var.tableau[10][88]);
          free(var.tableau);
          system("PAUSE");     
          return 0;
        }


        Citation : compilateur

        C:\Documents and Settings\stephane\Mes documents\programmation\c\test\PROG CONSOL\lecture\main.c In function `main':
        23 C:\Documents and Settings\stephane\Mes documents\programmation\c\test\PROG CONSOL\lecture\main.c subscripted value is neither array nor pointer
        24 C:\Documents and Settings\stephane\Mes documents\programmation\c\test\PROG CONSOL\lecture\main.c subscripted value is neither array nor pointer
        C:\Documents and Settings\stephane\Mes documents\programmation\c\test\PROG CONSOL\lecture\Makefile.win [Build Error] [main.o] Error 1

        • Partager sur Facebook
        • Partager sur Twitter
          16 juin 2006 à 12:07:53

          typedef struct Affichage Affichage;
          struct Affichage
            {
            int largeur; //nombre de case en largeur (cette variable varie dans l'interval [300;500] )
            int hauteur; //nombre de case en hauteur
            int *tableau; //Je veut creer le tableau a 2 dimention ici, mais je veut le faire dynamiquement
            };

          /* ... */

          var.tableau[10][88] = 10;


          Il y a un problème sur cette dernière ligne.
          Quel est le type de var.tableau[10] ?

          C'est un int, n'est-ce pas ?

          Dans ce cas, que peut bien signifier x[88], pour x de type int ?

          Réponse : pas grand chose.

          En fait, tu as deux solutions :
          • Première solution, remplacer le pointeur tableau par un double pointeur, de type int**. Dans ce cas, var.tableau est de type int**, var.tableau[10] est de type int*, et var.tableau[10][88] a du sens. N'oublie pas dans ce cas de modifier ton malloc, qui doit t'allouer de l'espace pour chaque int* (boucle). Mais ce n'est pas, je pense, la bonne solution
          • Deuxième solution, tu gardes la même forme pour ton programme, mais c'est l'accession aux élément qui va changer. En fait, au lieu d'écrire var.tableau[i][j], tu vas écrire var.tableau[i * var.largeur + j]. C'est comme si tu étalais un tableau à deux dimension en une seule, en mettant toutes tes lignes les unes à la suite des autres sur une droite horizontale. Cette solution est préférable, car tu ne t'encombres pas de pointeurs à libérer dans tous les sens, ce qui peut être délicat. Ici, un seul pointeur, pointant sur un gros espace.

          • Partager sur Facebook
          • Partager sur Twitter
            16 juin 2006 à 12:13:25

            Mais c'est parce que on fait pas un tableau à deux dimensions par allocation dynamique comme cela !

            Là tu as fait un tableau simple de int de 100*20=2000 cases !
            Déjà dans la structure il faut mettre int **tableau; je pense.

            Ensuite tu fait une alloc pour faire un tableau simple par exemple avec car.largueur ; ensuite par une boucle, pour chaque case de ce simple tableau (attention la case est *tableau[i] vu que c'est un double pointeur et pour ton alloc c'est pareil tu utilise *tableau), donc pour chaque case du tableau du fait une alloc dynamique avec var.hauteur !

            J'édite pour te mettre le code !

            Edit : code :
            #include <stdio.h>
            #include <stdlib.h>


            typedef struct Affichage Affichage;
            struct Affichage
              {
              int largeur; //nombre de case en largeur (cette variable varie dans l'interval [300;500] )
              int hauteur; //nombre de case en hauteur
              int **tableau; //Je veut creer le tableau a 2 dimention ici, mais je veut le faire dynamiquement
              };

            int main(int argc, char *argv[])
            {
              Affichage var;
             
              var.largeur = 100;
              var.hauteur = 20;
              var.(*tableau) = malloc(sizeof(int) * var.largeur);
              for (i=0 ; i<var.largeur ; i++)
              {
                var.tableau[i] = malloc(sizeof(int) * var.hauteur);
              }
             
              var.tableau[10][88] = 10;
              printf("%d",var.tableau[10][88]);
              free(var.tableau);
              system("PAUSE");     
              return 0;
            }


            Je pense que cela est bon !
            Après je peux me tromper ...

            PS : si ça ne marche pas remplace var.tableau[i] dans le boucle par var.(*tableau[i]) (encore une fois pas sûr que ça marche !)
            • Partager sur Facebook
            • Partager sur Twitter
              16 juin 2006 à 12:20:49

              Pierre89 -> ok

              Citation : yoxo

              * Deuxième solution, tu gardes la même forme pour ton programme, mais c'est l'accession aux élément qui va changer. En fait, au lieu d'écrire var.tableau[i][j], tu vas écrire var.tableau[i * var.largeur + j]. C'est comme si tu étalais un tableau à deux dimension en une seule, en mettant toutes tes lignes les unes à la suite des autres sur une droite horizontale. Cette solution est préférable, car tu ne t'encombres pas de pointeurs à libérer dans tous les sens, ce qui peut être délicat. Ici, un seul pointeur, pointant sur un gros espace.

              effectivement en faissant comme ci dessus ca marche, mais je préfère avec 2 dimention je pense que je m'en sortirais mieu.

              [EDIT] Imposible de compiler le code on a pas le droit de faire comme ca
              var.(*tableau)
              le compilateur me dit erreur avant '('

              J'ai essaye en enlevant les parenthese et l'étoile et ca marche.

              Merci beaucoup de votre aide.
              • Partager sur Facebook
              • Partager sur Twitter
                16 juin 2006 à 12:29:23

                Citation : Pierre89

                Mais c'est parce que on fait pas un tableau à deux dimensions par allocation dynamique comme cela !

                Là tu as fait un tableau simple de int de 100*20=2000 cases !
                Déjà dans la structure il faut mettre int **tableau; je pense.

                Ensuite tu fait une alloc pour faire un tableau simple par exemple avec car.largueur ; ensuite par une boucle, pour chaque case de ce simple tableau (attention la case est *tableau[i] vu que c'est un double pointeur et pour ton alloc c'est pareil tu utilise *tableau), donc pour chaque case du tableau du fait une alloc dynamique avec var.hauteur !

                J'édite pour te mettre le code !

                Edit : code :

                #include <stdio.h>
                #include <stdlib.h>


                typedef struct Affichage Affichage;
                struct Affichage
                  {
                  int largeur; //nombre de case en largeur (cette variable varie dans l'interval [300;500] )
                  int hauteur; //nombre de case en hauteur
                  int **tableau; //Je veut creer le tableau a 2 dimention ici, mais je veut le faire dynamiquement
                  };

                int main(int argc, char *argv[])
                {
                  Affichage var;
                 
                  var.largeur = 100;
                  var.hauteur = 20;
                  var.(*tableau) = malloc(sizeof(int) * var.largeur);
                  for (i=0 ; i<var.largeur ; i++)
                  {
                    var.tableau[i] = malloc(sizeof(int) * var.hauteur);
                  }
                 
                  var.tableau[10][88] = 10;
                  printf("%d",var.tableau[10][88]);
                  free(var.tableau);
                  system("PAUSE");     
                  return 0;
                }



                Je pense que cela est bon !
                Après je peux me tromper ...



                En effet tu te trompe :p

                pourquoi var.(*tableau)? déjà ça n'a aucun sens, et ensuite c'est pas du tout de qu'il faut faire.

                var.tableau pointe sur un tableau de pointeur d'entiers. donc:

                var.tableau = malloc(sizeof(int *) * var.largeur);


                Le reste est bon, sauf qu'il faudrait rajouter un

                for (i = 0; i < var.largeur; ++i)
                    free(var.tableau[i]);


                Pour bien libérer toute la mémoire.

                Puis faut déclarer i aussi :p
                • Partager sur Facebook
                • Partager sur Twitter
                  16 juin 2006 à 12:35:11

                  Citation : dark-lord

                  effectivement en faissant comme ci dessus ca marche, mais je préfère avec 2 dimention je pense que je m'en sortirais mieu.


                  Je pense que tu as tort, il vaut mieux prendre des bonnes habitudes tôt. Mais tu fait comme tu veux. Je te modifie dans ce cas le code (main) de Pierre89, qui est partiellement faux.

                  int main(int argc, char *argv[])
                  {
                    Affichage var;
                   
                    var.largeur = 100;
                    var.hauteur = 20

                    /* var.tableau est un int**, on lui alloue var.hauteur
                       elements de type int *. On peut aussi (et c'est mieux)
                       remplacer sizeof(int *) par sizeof var.tableau */

                    var.tableau = malloc(sizeof(int *) * var.hauteur)
                   
                    for (i=0 ; i<var.hauteur ; i++)
                    {
                      /* var.tableau[i] est de type int*, on lui alloue var.largeur
                         elements de type int. De meme, il vaut mieux remplacer
                         sizeof(int) par sizeof var.tableau[i] */

                      var.tableau[i] = malloc(sizeof(int) * var.largeur);
                    }
                   
                    var.tableau[10][88] = 10;
                    printf("%d",var.tableau[10][88]);
                    free(var.tableau);
                    system("PAUSE");     
                    return 0;
                  }


                  Edit : il faut bien sûr déclarer i, et puis libérer toutes les allocations (fastidieux, comme je l'avais mentionné), cf le post de drexil.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    16 juin 2006 à 12:37:23

                    Ouais c'est ça que je voulais faire mais je partais de l'intérieur pour aller vers l'extérieur au lieu de l'inverse et comme vous avez fait c'est plus logique en effet ! ^^
                    • Partager sur Facebook
                    • Partager sur Twitter

                    Encore une question sur les structures

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown