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 :

Tableau multidimensionnel avec différentes tailles


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut Tableau multidimensionnel avec différentes tailles
    Bonjour à tous

    j'aurais besoin de plusieurs tableaux un peu comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    const uint16_t prog[4][] = {512,256,128,64,32,13,8,4,2,1},
                               {0,48,120,252,510,1023},
                               {48,72,132,258,513,258,132,72},
                               {585,292,146};
    Bien sûr cela ne fonctionne pas. mais c'est l'idée.
    Y a t'il une solution pour le faire.
    Ou alors peut-on construire les tableaux un par un avec un indice x comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    const uint16_t prog1[] = {512,256,128,64,32,13,8,4,2,1};
    const uint16_t prog2[] = {0,48,120,252,510,1023};
    const uint16_t prog3[] = {48,72,132,258,513,258,132,72};
    const uint16_t prog4[] = {585,292,146};
    Et dans ce cas comment accéder aux données en appelant avec l'indice 'progx'

    Merci
    Michel

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Déjà, lorsque tu déclares un tableau multi-dimentionnel, il n'y a que la première dimension qui puisse ne pas avoir de limites.
    Or, dans le code que tu présentes, il n'y a -- justement -- que la première dimension qui en aie une.

    Un code qui pourrait marcher serait donc plus proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    /* on précise les tailles pour les deux dimensions */
    uint16_t tab[4][6]={
                       {1,2,3,4,5,6},
                       {1,2,3,4,7,8},
                       {9,8,7,6,5,4},
                       {1,2,3,4,9,1}
    };
    voir, au pire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    /* il n'y a que la première dimension qui peut
     * ne pas être précisée
     */
    uint16_t tab[][6]={
                       {1,2,3,4,5,6},
                       {1,2,3,4,7,8},
                       {9,8,7,6,5,4},
                       {1,2,3,4,9,1}
    };
    Sauf que, du coup, ben, cela t'obligerait à avoir un nombre d'éléments identique dans chacun des tableaux, ce qui n'est peut-être pas ce que tu souhaite.

    Par contre, tu auras remarqué que les différents tableaux, qui sont représentés par les paires ("intérieures") d'accolade { et } sont eux même entourés d'une paire d'accolade "englobante" pour représenter, justement, la première dimension .

    L'un des problèmes de ton code (hormis le fait que seule la première dimension peut se permettre de ne pas avoir de limites) étant que tu as oublié cette paire d'accolade "englobante".

    Ceci dit, tu es dans la sections C++, et il faut savoir que la plupart des pratiques "communes en C" sont le plus souvent des "pièges à cons" en C++. Si bien que l'on aura généralement tendance à les éviter "comme la peste".

    Si tu as vraiment besoin d'un nombre fixe de tableaux de tailles potentiellement différentes, je te conseillerais de te tourner vers les classes fournies par la bibliothèque standard du C++, juste histoire de te faciliter la vie.

    Pour les tableau de taille fixe (par exemple, pour le fait que tu veux explicitement quatre tableau de tailles potentiellement différentes) je te conseillerais de te tourner vers la classe std::array

    C'est une classe qui agit exactement comme les tableau de taille fixe "classiques", à ceci prêt qu'elle présente l'énorme avantage de connaitre sa taille en permanence.
    son utilisation "classique" consiste à définir un tableau sous la forme de std::array<TypeDesElement, nombreDelements> tab;. Tu peux d'ailleurs en déclarer très facilement un alias de type pour t'éviter d'avoir un texte imbitable à écrire à chaque fois ;-)

    Pour ce qui est des tableaux dont la taille est définie à l'exécution, il existe la classe std::vector.

    Il s'agit d'une classe qui fera exactement tout ce que tu ferais en C à coup de malloc/calloc/realloc et free, à ceci près qu'elle le fera de manière automatique exactement au bon moment et de manière "sécurisée".

    Si donc, tu veux un nombre précis de tableaux de tailles variables, tu pourrais très bien envisager d'avoir un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    std::array<std::vector<uint16_t>,4> tab={{
        {1,2,3,4},
        {1,2,3,4,5,6},
        {9,8,7,6},
        {9,8,7,6,5,4,3,2,1}
    }};
    avec, bien sur, la possibilité de définir un alias de type pour te faciliter la vie sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    using TabDeTab = std::array<std::vector<uint16_t>,4>;
    TabDeTab tab={{
        {1,2,3,4},
        {1,2,3,4,5,6},
        {9,8,7,6},
        {9,8,7,6,5,4,3,2,1}}
    };
    Ou, si tu veux d'avantage avoir un tableau de taille non définie à l'avance qui contienne des tableaux de taille fixe, tu pourrais envisager la solution inverse, à savoir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    std::vector<std::array<int, 4>> tab={{
        {1,2,3,4},
        {1,2,3,4,},
        {9,8,7,6},
        {9,8,7,6}}
    };
    Et, bien sur, les deux autres solutions -- à savoir un tableau de taille non définie contenant des tableaux de taille non définie ou un tableau de taille fixe contenant des tableaux de tailles fixes -- sont elles aussi tout à fait envisageables

    L'énorme avantage de travailler de la sorte étant que, si tu as besoin d'un tableau dont la taille risque de varier à l'exécution, tu pourras toujours ajouter des élément à un std::vector en utilisant simplement les foncitons membres push_back ou emplace_back (la différence est subtile, on en parlera un autre jour ) ou supprimer un élément en utilisant la fonction membre erase.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut
    Merci Koala01 pour ces explications.
    il n'y a -- justement -- que la première dimension qui en aie une.
    Oui je l'avais remarqué lors de la compilation mais comme je l'ai indiqué c'est l'idée de ce que j'ai besoin.
    Ok pour la paire d'accolades "englobantes".
    Par contre, je ne me sens pas capable de me lancer avec la classe std::vector car même après plusieurs relecture des liens, je n'ai pas vraiment tout compris.
    Alors je vais faire comme tu me le conseilles: avoir des tableaux de longueur fixe et pour écourter la lecture je vais décider d'un code de fin de tableau, 1024 par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    const uint16_t prog[4][10] = {
                               {512,256,128,64,32,13,8,4,2,1},
                               {0,48,120,252,510,1023,1024,0,0,0},
                               {48,72,132,258,513,258,132,72,1024,0},
                               {585,292,146,1024,0,0,0,0,0,0}
    };
    Bien sûr ce n'est pas optimisé pour la mémoire (surtout que je ne vais pas me limiter à 4, il y en aura peut-être une vingtaine), mais ça me paraît plus simple pour mes débuts.

    Cordialement
    Michel

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Puisqu'on est dans le forum C++, pourquoi ne pas utiliser du 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
    #include <iostream>
    #include <vector>
     
    int main()
    {
        const std::vector<std::vector<uint16_t>> prog = {
                               {512,256,128,64,32,13,8,4,2,1},
                               {0,48,120,252,510,1023},
                               {48,72,132,258,513,258,132,72},
                               {585,292,146}
        };
     
        for (const auto& vec : prog)
        {
            for (const uint16_t val : vec)
            {
                std::cout<<val<<",";
            }
            std::cout<<std::endl;
        }
     
        return 0;
    }
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par mormic Voir le message
    Par contre, je ne me sens pas capable de me lancer avec la classe std::vector car même après plusieurs relecture des liens, je n'ai pas vraiment tout compris.
    Alors, tu as largement plus intérêt à poser des questions sur ce qui te chagrine.

    S'il y a quelque chose que tu ne comprend absolument pas, ou même que tu as simplement du mal à visualiser ou à appréhender, dis toi que tu trouveras très certainement "quelqu'un" pour te donner les explications qui te manquent.

    Quoi qu'il en soit, si tu veux travailler en C++, tu as très largement intérêt à te familiariser le plus vite possible avec les fonctionnalités de la bibliothèque standard; tu verras qu'elle peut réellement te changer la vie

    Et la classe std::vector est, très clairement, l'une des classes qui te sera la plus utile
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut
    Ma difficulté c'est cette syntaxe qui n'est pas franchement intuitive:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const std::vector<std::vector<uint16_t>> prog =
    Ensuite je n'ai pas compris comment exploiter dans deux boucles imbriquées les données de mes tableaux. Comment les indicer?

    Je programme avec l'IDE d'Arduino (qui est du C++)

    Merci de votre aide

  7. #7
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Citation Envoyé par mormic Voir le message
    Ma difficulté c'est cette syntaxe qui n'est pas franchement intuitive:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const std::vector<std::vector<uint16_t>> prog =
    Ensuite je n'ai pas compris comment exploiter dans deux boucles imbriquées les données de mes tableaux. Comment les indicer?

    Je programme avec l'IDE d'Arduino (qui est du C++)

    Merci de votre aide
    C'est important de savoir que tu es en Arduino. Tu es sur un C++ très réduit, les vector<> doivent cependant exister.
    Comment indicer les vector<> ? Exactement comme les tableaux. Bousk t'a donné un moyen plus simple pour itérer dans les vector<> mais rien ne t'empêche d'utiliser des indices même si il y a plus de risques (se gourer d'indice, aller au delà du tableau...)
    Son exemple en utilisant des indices:
    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
    #include <iostream>
    #include <vector>
     
    int main()
    {
        const std::vector<std::vector<uint16_t>> prog = {
                               {512,256,128,64,32,13,8,4,2,1},
                               {0,48,120,252,510,1023},
                               {48,72,132,258,513,258,132,72},
                               {585,292,146}
        };
     
        for ( size_t i = 0 ; i < prog.size() ; ++i )
        {
            for ( size_t j = 0 ; j < prog[i].size() ; ++j )
            {
                std::cout << prog[i][j] << ",";
            }
            std::cout<<std::endl;
        }
     
        return 0;
    }

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

Discussions similaires

  1. [Python 3.X] Afficher un tableau (cellule de différente taille)
    Par toitoinebzh dans le forum Général Python
    Réponses: 8
    Dernier message: 14/06/2021, 14h15
  2. Réponses: 6
    Dernier message: 08/10/2018, 20h15
  3. Réponses: 5
    Dernier message: 12/12/2013, 11h43
  4. Requête tableau, tri avec différents cas
    Par Jefty dans le forum Langage SQL
    Réponses: 6
    Dernier message: 15/03/2012, 14h34
  5. Réponses: 5
    Dernier message: 20/03/2007, 01h56

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