Partage
  • Partager sur Facebook
  • Partager sur Twitter

Fonction de création de tableau2D

Sujet résolu
    1 septembre 2021 à 15:37:03

    #include <stdio.h>
    #include <stdlib.h>
     
     
    #define LIGNE_TABLEAU 5
    #define COLONNE_TABLEAU 4
     
    int *cree_tableau(void);
     
     
    int main(void)
    {
        int i = 0, j = 0;
        
        //char *tableau = creeTableau();
        int *tab = cree_tableau();
     
        for (int i = 0; i < 5; ++i)
        {
            for( j = 0; j < COLONNE_TABLEAU; j++)
            {
                printf("[%d] ",tab[i][j]);
     
            }
        }
        return 0;
     
    }
        
     
     
     
     
     
    int *cree_tableau(void)
    {
        int i =0, j = 0;
        static int tableau_entier[LIGNE_TABLEAU][COLONNE_TABLEAU];
     
        for (int i = 0; i < 5; ++i)
        {
            for (int j = 0; j < COLONNE_TABLEAU; ++j)
            {
                tableau_entier[i][j] = i + j * 3;
            }
            
        }
     
        return tableau_entier;
    }


    Bonjour à tous 

    voici mon problème, j'ai tenté de créer une fonction qui crée un tableau en deux dimension 

    voici le code :  https://pastebin.com/2TqEjJnG

    et voici le message d'erreur que je reçois : 

    test.c: In function 'cree_tableau':

    test.c:23:16: warning: returning 'int (*)[4]' from a function with incompatible return type 'int *' [-Wincompatible-pointer-types]

       23 |         return tableau_entier;

          |                    ^~~~~~~~~~~~~~

    test.c: In function 'main':

    test.c:39:46: error: subscripted value is neither array nor pointer nor vector

       39 |                         printf("[%d] ",tab[i][j]);

          |                                                         ^

    J'avoue être confus et ne pas bien comprendre le sens des erreurs qu'il m'indique d'autant plus que le même code avec un tableau à une seul dimension fonctionne correctement. 

    Merci d'avance pour vos réponses. 

    -
    Edité par GuillaumePerez2 1 septembre 2021 à 16:43:52

    • Partager sur Facebook
    • Partager sur Twitter
      1 septembre 2021 à 15:55:41

      Utilises le bouton code </> du forum pour poster ton code ! (tu peux modifier ton post, lien modifier en haut à droite du post).
      • Partager sur Facebook
      • Partager sur Twitter
        1 septembre 2021 à 17:01:52

        rouIoude a écrit:

        Utilises le bouton code </> du forum pour poster ton code ! (tu peux modifier ton post, lien modifier en haut à droite du post).

        Oui merci je vais faire ça
        • Partager sur Facebook
        • Partager sur Twitter
          1 septembre 2021 à 18:00:04

          Bonjour,

          GuillaumePerez2 a écrit:

          test.c:23:16: warning: returning 'int (*)[4]' from a function with incompatible return type 'int *' [-Wincompatible-pointer-types]

             23 |         return tableau_entier;

                |                    ^~~~~~~~~~~~~~

          Le type de la fonction, telle qu'elle est déclarée, n'est pas celui de la valeur retournée.

          Effectivement, voici la déclaration de la fonction :

          int *cree_tableau(void);

          Elle est de type int*, donc doit retourner une valeur de type int*. Ce type est équivalent à int[], qui est adapté à un tableau à 1 dimension.

          Or tu retournes :

              static int tableau_entier[LIGNE_TABLEAU][COLONNE_TABLEAU];
              return tableau_entier;

          qui est de type int[][], fait pour un tableau à 2 dimensions.

          Si tu veux retourner un tableau à 2 dimensions, peut-être qu'il faut déclarer la fonction comme étant de type int**. Mais je crois que ce n'est pas si simple.

          GuillaumePerez2 a écrit:

          test.c:39:46: error: subscripted value is neither array nor pointer nor vector

             39 |                         printf("[%d] ",tab[i][j]);

                |                                                         ^

          Toujours le même genre d'erreur : tu utilises deux indices pour 'tab', comme si c'était un tableau à 2 dimensions. Est-ce le cas ?

          int *tab = cree_tableau();

          Non : il est de type int*, qui est équivalent à int[] : ça déclare un tableau à 1 dimensions. Peut-être qu'il faut déclarer 'tab' comme était de type int**. Là aussi je crains que ce ne soit pas si simple.

          -
          Edité par robun 1 septembre 2021 à 18:06:20

          • Partager sur Facebook
          • Partager sur Twitter
            1 septembre 2021 à 18:20:20

            Il faut le faire dans la définition de la fonction et du pointeur dans le main ('**' dans les deux cas)
            Il y a un problème plus grave. Qui dira au compilateur le nombre de colonnes du tableau dans le main?
            Ce truc marche avec les tableaux dynamiques utilisant malloc, ce qui n'est pas le cas ici.
            Je suggère plutôt de déclarer le tableau dans le main et de seulement l'initialiser dans la fonction.
            On dit à la fonction le nombre de colonnes (déclaration)
            • Partager sur Facebook
            • Partager sur Twitter

            Le Tout est souvent plus grand que la somme de ses parties.

              1 septembre 2021 à 18:34:26

              Quel est le but de retourner un tableau static ? Parce que il y a surement meilleur solution !

              Parce que la pour que ça marche tu vas être obligé de faire des casts (transtypage).

              • Partager sur Facebook
              • Partager sur Twitter
                1 septembre 2021 à 18:56:06

                robun a écrit:

                Bonjour,

                GuillaumePerez2 a écrit:

                test.c:23:16: warning: returning 'int (*)[4]' from a function with incompatible return type 'int *' [-Wincompatible-pointer-types]

                   23 |         return tableau_entier;

                      |                    ^~~~~~~~~~~~~~

                Le type de la fonction, telle qu'elle est déclarée, n'est pas celui de la valeur retournée.

                Effectivement, voici la déclaration de la fonction :

                int *cree_tableau(void);

                Elle est de type int*, donc doit retourner une valeur de type int*. Ce type est équivalent à int[], qui est adapté à un tableau à 1 dimension.

                Or tu retournes :

                    static int tableau_entier[LIGNE_TABLEAU][COLONNE_TABLEAU];
                    return tableau_entier;

                qui est de type int[][], fait pour un tableau à 2 dimensions.

                Si tu veux retourner un tableau à 2 dimensions, peut-être qu'il faut déclarer la fonction comme étant de type int**. Mais je crois que ce n'est pas si simple.

                GuillaumePerez2 a écrit:

                test.c:39:46: error: subscripted value is neither array nor pointer nor vector

                   39 |                         printf("[%d] ",tab[i][j]);

                      |                                                         ^

                Toujours le même genre d'erreur : tu utilises deux indices pour 'tab', comme si c'était un tableau à 2 dimensions. Est-ce le cas ?

                int *tab = cree_tableau();

                Non : il est de type int*, qui est équivalent à int[] : ça déclare un tableau à 1 dimensions. Peut-être qu'il faut déclarer 'tab' comme était de type int**. Là aussi je crains que ce ne soit pas si simple.

                -
                Edité par robun il y a moins de 30s

                Merci robin d'avoir prit le temps de me répondre  je comprend maintenant d'où vient l'erreur. Mais je ne comprend malheureusement pas comment la corriger ne comprenant pas comment l'on peut créer des types int**. Auriez vous des idées ou des pistes à explorer ? 

                • Partager sur Facebook
                • Partager sur Twitter
                  1 septembre 2021 à 19:05:51

                  Pourquoi créer des tableaux de type int** ? Tu veux que les dimensions soient variables?
                  Ça se fait avec malloc, pas un tableau statique.
                  Tu réserves un tableau de LIGNE_TABLEAU pointeurs
                  Pour chaque entrée, tu réserves COLONNE_TABLEAU places pour des int
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Le Tout est souvent plus grand que la somme de ses parties.

                    1 septembre 2021 à 19:07:57

                    rouIoude a écrit:

                    Quel est le but de retourner un tableau static ? Parce que il y a surement meilleur solution !

                    Parce que la pour que ça marche tu vas être obligé de faire des casts (transtypage).

                    Bon apparemment tu tiens à ta solution bancale, je te met donc le code :

                    #include <stdio.h>
                    
                    #define LIGNE_TABLEAU 5
                    #define COLONNE_TABLEAU 4
                    
                    int* cree_tableau(void);
                    
                    int main(void)
                    {
                        int (*tab)[COLONNE_TABLEAU] = (int(*)[COLONNE_TABLEAU])cree_tableau();
                    
                        for (int i = 0; i < 5; ++i)
                        {
                            for(int j = 0; j < COLONNE_TABLEAU; j++)
                            {
                                printf("[%d] ",tab[i][j]);
                            }
                        }
                        return 0;
                    }
                    
                    
                    int *cree_tableau(void)
                    {
                        static int tableau_entier[LIGNE_TABLEAU][COLONNE_TABLEAU];
                    
                        for (int i = 0; i < LIGNE_TABLEAU; ++i)
                        {
                            for (int j = 0; j < COLONNE_TABLEAU; ++j)
                            {
                                tableau_entier[i][j] = i + j * 3;
                            }
                        }
                        return (int *)tableau_entier;
                    }




                    • Partager sur Facebook
                    • Partager sur Twitter
                      1 septembre 2021 à 19:10:43

                      PierrotLeFou a écrit:

                      Pourquoi créer des tableaux de type int** ? Tu veux que les dimensions soient variables?
                      Ça se fait avec malloc, pas un tableau statique.
                      Tu réserves un tableau de LIGNE_TABLEAU pointeurs
                      Pour chaque entrée, tu réserves COLONNE_TABLEAU places pour des int

                      N'est il pas possible de le faire sans utiliser l'allocation dynamique. Je veux un tableau de taille fixe ayant pour dimensions les valeurs des directives de préprocesseurs.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        1 septembre 2021 à 19:34:58

                        Hello,

                        Alors tu le mets en global (c'est pas interdit, à condition de savoir l'employer)

                        #define NROWS     10
                        #define NCOLS     55
                        
                        int array[NROWS][NCOLS];



                        -
                        Edité par edgarjacobs 1 septembre 2021 à 19:36:50

                        • Partager sur Facebook
                        • Partager sur Twitter

                        Il y a ceux qui font des sauvegardes, et ceux qui n'ont pas encore eu d'incident....

                          1 septembre 2021 à 19:36:20

                          En déclarant le tableau dans le main, ça va suivre les indications du préprocesseur.
                          Tu n'as qu'à passer les dimensions à la fonction.
                          Tu as une autre option, c'est de faire un tableau à une seule dimension de ggrandeur [LIGNE_TABLEAU * COLONNE_TABLEAU]
                          Au lieu de faire tableau[i][j], tu fais tableau[i *COLONNE_TABLEAU + j]
                          • Partager sur Facebook
                          • Partager sur Twitter

                          Le Tout est souvent plus grand que la somme de ses parties.

                            1 septembre 2021 à 20:00:34

                            rouIoude a écrit:

                            rouIoude a écrit:

                            Quel est le but de retourner un tableau static ? Parce que il y a surement meilleur solution !

                            Parce que la pour que ça marche tu vas être obligé de faire des casts (transtypage).

                            Bon apparemment tu tiens à ta solution bancale,

                            Il y a certainement mieux je veux bien vous croire, mais l'exercice que je tente résoudre ne demande pas plus que les tableaux fixe.

                            En revanche que signifie cette ligne j'ai du mal à la comprendre 

                            int (*tab)[COLONNE_TABLEAU] = (int(*)[COLONNE_TABLEAU])cree_tableau();

                            et je me demandais si ça marche aussi pour les tableaux de char.





                            • Partager sur Facebook
                            • Partager sur Twitter
                              1 septembre 2021 à 20:32:47

                              Avec un typedef c'est mieux :

                              #include <stdio.h>
                              
                              #define LIGNE_TABLEAU 5
                              #define COLONNE_TABLEAU 4
                              
                              typedef int(*PTCol)[COLONNE_TABLEAU];
                              
                              PTCol cree_tableau(void);
                              
                              int main(void)
                              {
                                  PTCol tab = cree_tableau();
                              
                                  for (int i = 0; i < 5; ++i)
                                  {
                                      for(int j = 0; j < COLONNE_TABLEAU; j++)
                                      {
                                          printf("[%d] ",tab[i][j]);
                                      }
                                  }
                                  return 0;
                              }
                              
                              
                              PTCol cree_tableau(void)
                              {
                                  static int tableau_entier[LIGNE_TABLEAU][COLONNE_TABLEAU];
                              
                                  for (int i = 0; i < LIGNE_TABLEAU; ++i)
                                  {
                                      for (int j = 0; j < COLONNE_TABLEAU; ++j)
                                      {
                                          tableau_entier[i][j] = i + j * 3;
                                      }
                                  }
                                  return tableau_entier;
                              }

                              ça évite les vilains transtypage.


                              GuillaumePerez2 a écrit:

                              rouIoude a écrit:

                              En revanche que signifie cette ligne j'ai du mal à la comprendre 

                              int (*tab)[COLONNE_TABLEAU] = (int(*)[COLONNE_TABLEAU])cree_tableau();

                              et je me demandais si ça marche aussi pour les tableaux de char.

                              ça déclare un pointeur tab sur des tableaux de COLONNE_TABLEAU élément, puis ça lui affecte l'adresse du tableau retourné par la fonction, mais comme elle retourne un pointeur sur int il faut le transtyper en pointeur sur des tableau de COLONNE_TABLEAU éléments.

                              Ça marche avec des char ou ce que tu veux. 

                              -
                              Edité par rouIoude 1 septembre 2021 à 20:38:54

                              • Partager sur Facebook
                              • Partager sur Twitter
                                1 septembre 2021 à 21:40:52

                                @rouIoude Bonsoir, je viens de retirer votre dernier message des spams.

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  1 septembre 2021 à 21:45:13

                                  Je pense que le plus simple est de déclarer le tableau dans le 'main' et de le passer en paramètre des fonctions. En paramètre : pas en valeur de retour.

                                  Exemple :

                                  #include <stdio.h>
                                  #include <stdlib.h>
                                   
                                  #define NB_LIG 5
                                  #define NB_COL 4
                                    
                                  void initialise_tableau(int tab[NB_LIG][NB_COL]);
                                  void affiche_tableau(int tab[NB_LIG][NB_COL]);
                                    
                                  int main(void)
                                  {
                                      int tableau[NB_LIG][NB_COL];
                                      initialise_tableau(tableau);
                                      affiche_tableau(tableau);
                                      return 0;
                                  }
                                  
                                  void initialise_tableau(int tab[NB_LIG][NB_COL])
                                  {
                                      for (int i = 0; i < NB_LIG; ++i)
                                      {
                                          for (int j = 0; j < NB_COL; ++j)
                                          {
                                              tab[i][j] = i + j * 3;
                                          }
                                      }
                                  }
                                  
                                  void affiche_tableau(int tab[NB_LIG][NB_COL])
                                  {
                                      for (int i = 0; i < NB_LIG; ++i)
                                      {
                                          for (int j = 0; j < NB_COL; ++j)
                                          {
                                              printf("%2d ", tab[i][j]);
                                          }
                                          printf("\n");
                                      }
                                  }
                                  

                                  Pas besoin de * partout (moins j'ai de *, mieux je me porte...)

                                  Résultat :

                                  robun@Ordi:~ > ./truc
                                   0  3  6  9 
                                   1  4  7 10 
                                   2  5  8 11 
                                   3  6  9 12 
                                   4  7 10 13 

                                  -
                                  Edité par robun 1 septembre 2021 à 21:47:10

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    1 septembre 2021 à 22:14:07

                                    rouIoude a écrit:

                                    Avec un typedef c'est mieux :

                                    #include <stdio.h>
                                    
                                    #define LIGNE_TABLEAU 5
                                    #define COLONNE_TABLEAU 4
                                    
                                    typedef int(*PTCol)[COLONNE_TABLEAU];
                                    
                                    PTCol cree_tableau(void);
                                    
                                    int main(void)
                                    {
                                        PTCol tab = cree_tableau();
                                    
                                        for (int i = 0; i < 5; ++i)
                                        {
                                            for(int j = 0; j < COLONNE_TABLEAU; j++)
                                            {
                                                printf("[%d] ",tab[i][j]);
                                            }
                                        }
                                        return 0;
                                    }
                                    
                                    
                                    PTCol cree_tableau(void)
                                    {
                                        static int tableau_entier[LIGNE_TABLEAU][COLONNE_TABLEAU];
                                    
                                        for (int i = 0; i < LIGNE_TABLEAU; ++i)
                                        {
                                            for (int j = 0; j < COLONNE_TABLEAU; ++j)
                                            {
                                                tableau_entier[i][j] = i + j * 3;
                                            }
                                        }
                                        return tableau_entier;
                                    }

                                    ça évite les vilains transtypage.


                                    GuillaumePerez2 a écrit:

                                    rouIoude a écrit:

                                    En revanche que signifie cette ligne j'ai du mal à la comprendre 

                                    int (*tab)[COLONNE_TABLEAU] = (int(*)[COLONNE_TABLEAU])cree_tableau();

                                    et je me demandais si ça marche aussi pour les tableaux de char.

                                    ça déclare un pointeur tab sur des tableaux de COLONNE_TABLEAU élément, puis ça lui affecte l'adresse du tableau retourné par la fonction, mais comme elle retourne un pointeur sur int il faut le transtyper en pointeur sur des tableau de COLONNE_TABLEAU éléments.

                                    Ça marche avec des char ou ce que tu veux. 

                                    -
                                    Edité par rouIoude il y a environ 1 heure

                                    Merci beaucoup ça marche au poil.

                                    On s'éloigne peut être du sujet initial du topic mais qu'est ce que c'est que "transtyper"

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      1 septembre 2021 à 23:04:06

                                      GuillaumePerez2 a écrit:

                                      On s'éloigne peut être du sujet initial du topic mais qu'est ce que c'est que "transtyper"

                                      C'est changer le type d'une variable lors de l'affectation à une variable d'un autre type.



                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        2 septembre 2021 à 0:46:02

                                        robun a écrit:

                                        Je pense que le plus simple est de déclarer le tableau dans le 'main' et de le passer en paramètre des fonctions. En paramètre : pas en valeur de retour.

                                        Exemple :

                                        #include <stdio.h>
                                        #include <stdlib.h>
                                         
                                        #define NB_LIG 5
                                        #define NB_COL 4
                                          
                                        void initialise_tableau(int tab[NB_LIG][NB_COL]);
                                        void affiche_tableau(int tab[NB_LIG][NB_COL]);
                                          
                                        int main(void)
                                        {
                                            int tableau[NB_LIG][NB_COL];
                                            initialise_tableau(tableau);
                                            affiche_tableau(tableau);
                                            return 0;
                                        }
                                        
                                        void initialise_tableau(int tab[NB_LIG][NB_COL])
                                        {
                                            for (int i = 0; i < NB_LIG; ++i)
                                            {
                                                for (int j = 0; j < NB_COL; ++j)
                                                {
                                                    tab[i][j] = i + j * 3;
                                                }
                                            }
                                        }
                                        
                                        void affiche_tableau(int tab[NB_LIG][NB_COL])
                                        {
                                            for (int i = 0; i < NB_LIG; ++i)
                                            {
                                                for (int j = 0; j < NB_COL; ++j)
                                                {
                                                    printf("%2d ", tab[i][j]);
                                                }
                                                printf("\n");
                                            }
                                        }
                                        

                                        Pas besoin de * partout (moins j'ai de *, mieux je me porte...)

                                        Résultat :

                                        robun@Ordi:~ > ./truc
                                         0  3  6  9 
                                         1  4  7 10 
                                         2  5  8 11 
                                         3  6  9 12 
                                         4  7 10 13 

                                        -
                                        Edité par robun il y a 26 minutes


                                        Ah oui c'est bien comme ça je te remercie.

                                        -
                                        Edité par GuillaumePerez2 2 septembre 2021 à 9:32:03

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          2 septembre 2021 à 1:24:44

                                          rouIoude a écrit:

                                          GuillaumePerez2 a écrit:

                                          On s'éloigne peut être du sujet initial du topic mais qu'est ce que c'est que "transtyper"

                                          C'est changer le type d'une variable lors de l'affectation à une variable d'un autre type.

                                          Il est impossible de changer le type d'une variable en C; il est fixé à la déclaration de la variable (on peut  compléter certains types, mais on s'éloigne du sujet).
                                          Le transtypage est l'opération consistant à produire une valeur de type Y à partir d'une valeur de type X.
                                          Par exemple

                                          123; // 123 (implicitement de type int)
                                          (long)123; // 123 transtypé en type long

                                          On peut utiliser le transtypage dans toutes les expressions, pas seulement les affectations.

                                          -
                                          Edité par Marc Mongenet 2 septembre 2021 à 1:26:35

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            2 septembre 2021 à 10:12:11

                                            Oui, tout à fait, je ne me suis pas bien exprimé. J'aurais du dire changer le type d'une expression.
                                            • Partager sur Facebook
                                            • Partager sur Twitter

                                            Fonction de création de tableau2D

                                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                            • Editeur
                                            • Markdown