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 :

assigner un tableau 2D sur un pointeur


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2006
    Messages : 45
    Par défaut assigner un tableau 2D sur un pointeur
    ce problème m'avait l'air idiot quand je me le suis posé, mais quand j'ai voulu le réaliser, c 'est moi qui avait l'air idiot ...

    donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    char tableau [30] [50];
     
    char ** pointeur;
     
    pointeur = tableau;
    passe pas ....

    cannot convert 'char (*)[50]' to 'char**'

    l'idée étant de passer par un pointeur où je ne suis pas obligé de spécifier le nombre d'éléménts et de pouvoir y acceder
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    char * texte = pointeur [5];
     
    char car = pointeur [5][10];
    j'ai tout essayé ... sauf la bonne réponse (si il y en a une)

  2. #2
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char tableau [30] [50];
    char ** pointeur; 
    pointeur = tableau;
    Le type de pointeur ne peut être char ** . Il doit être du type de tableau (à l'évaluation) soit " adresse d'un élément de tableau". Les éléments de tableau sont ici des char[50] et le type de pointeur est alors char (*)[50] (avec les parenthèses : pointeur sur un tableau de 50 char)

    Toutefois, utiliser ce type peut présenter des problèmes lors du passage du tableau en argument d'une fonction car alors la fonction est spécialisée pour des char [50] , il y a obligation de spécifier la dimension (50) et on ne peut la changer.
    Une autre possibilité est de "voir" le tableau sous une forme à une dimension. Dans cette optique, le tableau est vu comme un char [] et le type de pointeur sera char * , la dimension (50) est passée en argument (et la fonction peut travailler sur des tableaux dont la dimension est quelconque) mais c'est au programmeur de faire explicitement le calcul des indices
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    char tableau [30] [50];
    char (*p1)[50] = tableau;
    char * pointeur = (char *) tableau; 
    ....
     
    tableau[i][j] <-> p1[i][j]
    tableau[i][j] <-> pointeur [ i*50+j]
    Enfin, une autre possibilité est de construire ce tableau à partir d'un tableau de pointeur sur char : char *[30], chaque pointeur contenant l'adresse d'un sous- tableau char [50]. Il n'intervient plus alors que des tableaux à une dimension. Le type de pointeur serait alors char ** et on peut accéder aux éléments comme d'habitude par pointeur [ i][j].
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    char tab[30*50];
    char *tableau[30];
    char ** pointeur = tableau;
    for(i=0;i<30;i++) tableau[i] = tab+i*50;
    .....
    tableau[i][j] = ...; // ou
    pointeur[i][j] = ...;
    Voir la FAQ pour plus de détails.

  3. #3
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par diogene
    Enfin, une autre possibilité est de construire ce tableau à partir d'un tableau de pointeur sur char : char *[30], ....
    Une autre possibilité est de construire un tableau à partir d'un tableau de pointeur sur char....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    char **Tableau ;
     
    Tableau = malloc ( 30*sizeof(char*) );
    ....
    for ( i = 0 ; i < 30 ; i++ )
        Tableau[i] = malloc ( 50 ) ;
     
    Tableau[i][j] = ....
    ...
    strcpy ( Tableau[i], "..." );
    ...

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2006
    Messages : 45
    Par défaut
    impeccable

    ca c'est de la réponse comme je les aime

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2006
    Messages : 45
    Par défaut
    par contre, j'ai un autre problème maintenant ...

    comment on créer une fonction qui renvoi ce tableau ?

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Procède logiquement :

    Comment créer une fonction qui renvoie un entier ?

    2 possibilités :

    ou bien


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void Fonction ( .... , int *toto )
    Donc .....

    A toi d'essayer... Pour apprendre c'est mieux...

    Note : une indication : en général dans ce cas, la 2ième forme est la plus utilisée...

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2006
    Messages : 45
    Par défaut
    je voudrais plutot une fonction qui me retourne le pointeur
    pour faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char (*pointeur) [50] = getTableau ();
    le prob, c'est que je ne sais pas comment déclarer la fonction getTableau ()

  8. #8
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    pas très pratique....

    Mais les 2 solutions sont :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    int Fonction ( ..... , char ***Tableau )
    {
    ....
     
    *Tableau = malloc ( 30*sizeof(char*) );
    ....
    for ( i = 0 ; i < 30 ; i++ )
        (*Tableau)[i] = malloc ( 50 ) ;
     
     
      return statut ;
    }
    où statut sera erreur si allocation échoue et succès si ça a marché.

    ou bien

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    char **Fonction ( ..... )
    {
      char **Tableau ;
    ....
     
     Tableau = malloc ( 30*sizeof(char*) );
    ....
    for ( i = 0 ; i < 30 ; i++ )
         Tableau[i] = malloc ( 50 ) ;
     
     
      return Tableau ;
    }
    Et je dis que dans le cas des tableaux dans le style (2D, 3D, ND), en général la forme la plus courante est la première...

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2006
    Messages : 45
    Par défaut
    en fait c'est du c++ que je fait

    et donc
    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
     
    class Machin
     {
     private :
      char tableau [30][50];
     
     public :
      char ** getTableau ();
     };
     
    //avec
     
    char ** Machin::getTableau ()
     {
     return tableau;
     }
    cannot convert 'char (*)[50]' to 'char**'

  10. #10
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par ded jay
    en fait c'est du c++ que je fait
    ben à ce compte-là fallait aller sur C++


    Mais sinon prend la 1ière solution...

    Et d'autre part je ne crois pas que le compilo accepte que tu fasses

    char[30][50] = char**

    mais plutôt char[][]

    mais dans ce cas ça ne passera pas en retour de fonction...

    Encore une fois

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int getTableau ( char ***tableau )

  11. #11
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Citation Envoyé par souviron34
    Procède logiquement :

    Comment créer une fonction qui renvoie un entier ?

    2 possibilités :
    En fait : 3 possibilités!

    En C++, il ne faut pas oublier le passage par référence...
    qui est mieux qu'un pointeur quand on peut l'utiliser

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void Fonction ( .... , int &toto )
    {
       toto = 3;
    }

  12. #12
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Modifier des arguments passés par référence (ou par pointeur) c'est quand même une pratique à éviter à mon avis -- cela a cependant du sens dans certains cas.

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2006
    Messages : 45
    Par défaut
    donc,

    je suis obligé de passer un pointeur en parametre de la fonction ?

    je peu pas retourner simplement l'adresse de mon tableau ?

  14. #14
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 301
    Billets dans le blog
    2
    Par défaut
    Non, tu n'es pas obligé, mais c'est tout de même la meilleure solution. Cela te permetra d'éviter automatiquement certains écueils, et puis ça te permet également une gestion d'erreur plus simple: chaque fonction retourne un code d'erreur (un int typiquement).

    Ensuite, il y a un point à prendre en compte: le scope de la variable. Ici il s'git d'un tableau. On pourrait dire ça autrement: où va-t-il être alloué et détuit?

    Si ta fonction retourne un pointeur sur le tableau, cela signifie que c'est elle qui va l'allouer. Et cela signifie aussi que ce n'est pas elle qui va le détruire. D'un point de vue 'conception', ce n'est pas terrible (bien que j'avoue que cela puisse être nécessaire). L'avantage avec le passage par référence (en paramètre de ta fonction), c'est que tu peux faire en sorte que le bloc qui va appeler cette fonction soit "entièrement propriétaire" de ton tableau.

  15. #15
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Pour répondre spécifiquement au post #9, la situation n'a pas changé par rapport aux réponses du post #2 (y compris les contraintes sur la dimension 50). Par conséquent, on aurait :
    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
    class Machin
     {
     private :
      char tableau [30][50];
     public :
      char (*getTableau ())[50];
     };
     
    //avec
     
    char (*Machin::getTableau ())[50]
     {
     return tableau;
     }
    ....
    class Machin m;
     char (*p)[50] = m.getTableau();
    ou pour alléger l'écriture lourdingue des déclarations de fonctions :
    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
    typedef   char (*pTableau)[50];
    class Machin
     {
     private :
      char tableau [30][50];
     
     public :
      pTableau getTableau ();
     };
     
    //avec
     
    pTableau Machin::getTableau ()
     {
     return tableau;
     }
    .....
    class Machin m;
     pTableau p = m.getTableau();

  16. #16
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Non, tu n'es pas obligé, mais c'est tout de même la meilleure solution. Cela te permetra d'éviter automatiquement certains écueils
    Si une fonction doit produire un résultat, ce résultat doit être retourné.
    Modifier une variable passée en argument pour fournir un résultat est souvent une mauvaise conception.
    Il est mieux de faire en sorte que la fonction n'ait pas d'effet de bord d'un point de vue de l'état mémoire de ses paramètres (sauf s'il s'agit d'une fonction de transfert de ressources). C'est en partie pour ça qu'on préfère mettre des const partout.

    et puis ça te permet également une gestion d'erreur plus simple: chaque fonction retourne un code d'erreur (un int typiquement).
    En C++ on utilise les exceptions.

    Bon, reprenons donc ce sujet. Que cherches-tu exactement ?
    Déjà, construis ta structure de données avec les bons outils. Tu veux un tableau à deux dimensions ou un tableau de pointeurs vers des tableaux alloués dynamiquement ? Dans le deuxième cas, utilise un tableau de std::vector<char>, ou de std::string puisque ça a l'air d'être des chaînes de caractères.
    Tu veux pouvoir retourner ton tableau par valeur ? Remplace ton tableau par un boost::array, qui est la même chose, mais copiable.

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2006
    Messages : 45
    Par défaut
    merci pour tout

    la réponse de diogene convient parfaitement a ce que je veux faire

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 07/11/2008, 18h58
  2. Dev c++ en rade sur les pointeurs ?...
    Par Magicien d'Oz dans le forum C
    Réponses: 17
    Dernier message: 13/10/2005, 19h38
  3. questions sur les pointeurs
    Par Hyoga dans le forum C++
    Réponses: 17
    Dernier message: 08/01/2005, 23h25
  4. [Debutant][Tableau] Tableau indexé sur chaine de caractères
    Par SamRay1024 dans le forum Collection et Stream
    Réponses: 3
    Dernier message: 07/05/2004, 11h14
  5. Pb de débutant sur les pointeurs!!!
    Par benji17c dans le forum C
    Réponses: 6
    Dernier message: 30/09/2003, 17h50

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