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 :

conversion d'une matrice de taille m*n en un tableau uniligne de taille m*n


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Inscrit en
    Mai 2009
    Messages
    56
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 56
    Points : 29
    Points
    29
    Par défaut conversion d'une matrice de taille m*n en un tableau uniligne de taille m*n
    Bonjour,

    j'ai une matrice a[m][n] , quand je fais (int*)a , qu'est ce qui se passe?

    merci

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 56
    Points : 44
    Points
    44
    Par défaut
    Tu te retrouve avec un tableau de pointeur.

    Autrement dit pas du tout ce que tu veux faire.

    pour ce que tu veux faire c'est un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    int*	tab = new int[m * n + 1];
    int	total_index = 0;
     
    for (int i = 0; i < m; ++i)
    {
    	for (int ibis = 0; ibis < n; ++ibis)
    	{
    		tab[total_index] = a[i][ibis];
    		++total_index;
    	}
    }
    tab[total_index] = NULL;
    Voila j'ai pas test mais normalement ca fonctionne

    Ceci dit je te conseil de faire un objet qui gere automatiquement tes tableaux et de reviser les pointeurs :p

  3. #3
    screetch
    Invité(e)
    Par défaut
    non non non c'est pas un tableau de pointeurs, c'est un tableau de tableaux
    a[m][n] est représenté contigu en mémoire et si on le transforme en (int*) alors on obtient les lignes ou les colonnes a la suite les unes des autres (j'ai jamais su si c'etait les lignes ou les colonnes, quelqu'un de plus calé pourra te dire)
    je crois que c'est les lignes a la suite les unes des autres

    si m=n=2, et que la matrice a vaut a = { { 0, 1 }, { 2, 3 } }
    alors si on caste a en int* : b = (int*)a alors b sera un tablea de 4 éléments
    b = { 0, 1, 2, 3 }

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 56
    Points : 44
    Points
    44
    Par défaut
    si t'as un int** tu as un tableau de pointeur, chaque pointeur dans ce tableau pointant alors sur un tableau.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int** tab;
     
    (tab)--->(tab[0],       tab[1],      tab[2] ...)
                 |            |           |
                 V            V           V
              (tab[0][0]) (tab[1][0]) (tab[2][0])
              (tab[0][1]) (tab[1][1]) (tab[2][1])
              (tab[0][2]) (tab[1][2]) (tab[2][2])
    la valeur de tab est un poiteur (pointant sur la premiere case d'un tableau de pointeur)
    la valeur de tab[n] est un pointeur (pointant sur la premiere case d'un tableau d'int)
    la baleur de tab[n][m] est un int

    Donc caster un int** en in int* revient a avoir un tableau de pointeur !

    Autrement dit c'est totalement inutile !

  5. #5
    screetch
    Invité(e)
    Par défaut
    a[m][n] est un tableau de tableau ici, pas un tableau de pointeurs

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 56
    Points : 44
    Points
    44
    Par défaut
    Citation Envoyé par screetch Voir le message
    a[m][n] est un tableau de tableau ici, pas un tableau de pointeurs
    La question etant :

    quand je fais (int*)a , qu'est ce qui se passe?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int** tab2d; 
     
    int* tab1d = (int*)tab2d;
    tab2d est un tableau 2 dimensions d'int !
    tab1d est un tableau 1 dimension de pointeurs ...

  7. #7
    screetch
    Invité(e)
    Par défaut
    moi je l'ai compris comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int tab2d[2][2];
    int* tab1d = (int*)tab2d;
    et dans ce cas tab2d est un tableau de tableaux, pas un tableau de pointeurs

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 56
    Points : 44
    Points
    44
    Par défaut
    Oui mais il demandait si ce qu'il recuperait si il avait fasait ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int* tab1d =  (int*)tab2d;
    Moi j'appelle (tab1d) un tableau de pointeur vu que c'etait des pointeurs a l'origine.
    Ceci etant ils sont utilises comme des ints a cause du cast. On peut donc dire que tab1d est un tableau d'int (qui ont pour valeur des addresses).

    Enfin de toutes facons c'est un cast qui rime a rien ...

    Pour faire un tableau 1d a partir d'un tableau 2d il faut faire une copie des valeurs dans un nouveau tableau (comme dans mon premier post).

  9. #9
    Nouveau membre du Club
    Inscrit en
    Mai 2009
    Messages
    56
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 56
    Points : 29
    Points
    29
    Par défaut
    je vous explique :
    j'ai une classe MatriceCreux dont l'un des attributs est int *P (c'est donc un pointeur sur entier) . une des methodes de la classe Matrice est modifierpointeur dont le corps est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void MatriceCreux::modifierpointeur(int *b)
    {
    	P=b;
    }
    cette methode appliquée à un objet MatriceCreux , fait pointer l'attribut P de cette MatriceCreux sur l'entier passé en argument.

    dans une autre méthode de la classe qui prend entre autre en argument un objet MatriceCreux M,j'ai initialisé une matrice a[n][m] , puis j'ai fait mon boutot .. juste avant la fin de cette classe ,j'ai fait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    M.modifierpointeur((int *)a);
    donc desormais le pointeur de M va pointer sur un tableau uniligne de taille n*m .

    dites moi s'il vous plait ,si mon raisonnement est juste .merci

  10. #10
    screetch
    Invité(e)
    Par défaut
    Enfin de toutes facons c'est un cast qui rime a rien ...

    Pour faire un tableau 1d a partir d'un tableau 2d il faut faire une copie des valeurs dans un nouveau tableau (comme dans mon premier post).
    NON! pinaise
    ca dépend du tableau 2d de depart mais si c'est une matrice genre int a[2][2] alors on peut le caster en tableau 1d et les valeurs seront contigues

  11. #11
    Nouveau membre du Club
    Inscrit en
    Mai 2009
    Messages
    56
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 56
    Points : 29
    Points
    29
    Par défaut
    oui oui ,lamatrice au debut est
    a[100][3] . et donc là ca marche ??
    le pointeur P va pointer sur le premier element de ce tableau?

  12. #12
    screetch
    Invité(e)
    Par défaut
    oui, la il y a 300 entiers cote a cote dans le tableau, je ne sais plus dans quel ordre exactement (je confond toujours) mais ils sont cote a cote en memoire

  13. #13
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Dans tout les cas les cast C-like c'est moche et a bannir..
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 56
    Points : 44
    Points
    44
    Par défaut
    Citation Envoyé par screetch Voir le message
    NON! pinaise
    ca dépend du tableau 2d de depart mais si c'est une matrice genre int a[2][2] alors on peut le caster en tableau 1d et les valeurs seront contigues
    Ok on s'est pas compis je partais pas sur le principe que sa matrice n'etait pas de taille fixe mais te taille varriable.

    Si l'alocation est fixe :

    Alors oui le cast fonctionnera (j'ai lu ton dernier message un peu vite ).

    En revanche si le tableau est de taille varriable et que l'allocation est du genre:



    Comme le montre le debug il se retrouve bien avec un tableau contenant la valeurs des pointeurs ...

    C'est pour ca que je lui conseillait de faire objet permetant de simuler un tableau 2d avec un tableau 1d (comme le fait le C++ avec la declaration "int tab[2][2]"). Histoire d'eviter quelques news.

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Avec un tableau 2D alloué dynamiquement de cette manière, ça marche aussi (vu que c'est la conversion inverse qui est faite pour remplir le tableau de pointeurs).

    Et bien sûr, les casts C-style sont à éviter. Pour la conversion int[2][2] vers int*, je conseillerais plutôt un reinterpret_cast, ou tout simplement un &tab2d[0][0].
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #16
    Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 56
    Points : 44
    Points
    44
    Par défaut
    Excuse moi mais je ne vois pas la difference entre la methode que je montre sur le screen de VS.
    Mise a part le fait que ce soir du C il y a quand meme une allocation pour l'index et une allocation pour chaque ligne !

  17. #17
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ma méthode ne fait pas une allocation pour chaque ligne, elle les alloue toutes d'un seul coup.
    • Le screen de VS fait 1+n allocations:
      • 1 allocation de n,
      • n allocations de m.
    • Ma méthode fait 2 allocations:
      • 1 allocation de n,
      • 1 allocation de n*m.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  18. #18
    Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 56
    Points : 44
    Points
    44
    Par défaut
    Ha oui :p

    Encore une fois j'ai lu trop vite

    Et effectivement en c'est une tres bonne methode (que j'ai deja utilise) mais un peu plus compliquee que celle consistant a faire un malloc par ligne.

    Sinon pour pousser un peu tu as essaye de le faire en 1 seul malloc ?
    En theorie ca devrait etre possible avec quelques casts.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    malloc(sizeof(ptr1) * 3 + sizeof(data) * 2);
     
           ------------------v
    [ptr][ptr][NULL][data][data]
      -----------------^
    Par contre avec ces methods il faut faire attention aux overflows. Valgrind ne dira rien en cas de debordement :p

    Je testerais peut etre si j'ai le temps.

  19. #19
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Et aussi faire attention aux contraintes d'alignement, je pense.

    un peu plus compliquee que celle consistant a faire un malloc par ligne
    J'ai l'impression que si on prend en compte la gestion d'erreurs, c'est plus simple en fait. Dans la version "un malloc par ligne", si l'allocation d'une ligne échoue, il faut désallouer toutes les autres avant de désallouer les pointeurs.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Conversion d'une matrice en tableau de cellules
    Par wawrint dans le forum MATLAB
    Réponses: 2
    Dernier message: 03/06/2008, 14h55
  2. Réponses: 2
    Dernier message: 26/06/2007, 15h40
  3. Réponses: 4
    Dernier message: 06/06/2007, 13h32
  4. Réponses: 4
    Dernier message: 05/05/2007, 19h12
  5. taille du browser adaptée à un tableau dont la taille varie
    Par grinder59 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 03/01/2006, 12h46

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