1. #1
    Membre du Club
    Profil pro
    Inscrit en
    janvier 2010
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2010
    Messages : 142
    Points : 59
    Points
    59

    Par défaut affecter un pointeur sur un tableau 2D à un pointeur de tableau 1D

    Bonjour,

    J'ai un pointer sur un tableau en deux dimension Ce tableau contient L linge et C colonne. Je veux affecter son contenu dans un tableau 1D. Pour l'instant je procède comme indiqué ci-dessous.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    		double* tab1D = NULL;
    		data = new double[L*C];
    		for (int i = 0; i < L; i++)
    		{
    			for (int j = 0; j < C; j++)
    			{
    				tab1D[(i*C) + j] tab2D[i][j] ;
    			}
    		}
    Ce code marche bien mais je voudrais savoir si c'est possible d'éviter de passer par la double boucle for en affectant directement le pointeur ?
    Aussi je veux pouvoir copier dans un tableau 1D de types différents (double, int, short int). Est ce qu'il y 'aurait un moyen de factoriser l'allocation mémoire du tableau et ne faire qu'un cast une fois l'affectation effectuée

    Merci

  2. #2
    Membre émérite
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 548
    Points : 2 856
    Points
    2 856

    Par défaut

    Les deux objets pointeur sur tableau de pointeur de T et pointeur sur T ne pointent pas sur des données identiques. Donc on ne peut pas effectuer l'affectation autrement qu'en copiant l'ensemble des données pointées par le premier vers la zone pointée par le second.
    Cette copie nécessite un double parcours.
    Le mieux serait déjà d'éviter d'utiliser ces types directement issus du langage C et de préférer les types du C++, et de créer le type correspondant à ton besoin.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template<typename T> class Tab1D {
       std::vector<T>  data;
    public:
       template<typename U>
       Tab1D( std::size_t nbl, std::size_t nbc, U const*const* arr2D ) : data(nbl*nbc) {
          for ( std::size_t i = 0 ;  i < nbl ;  ++i )
             std::copy_n( arr2D[i] , nbc , &data[i*nbc] ); // copie la ligne (peut convertir si nécessaire)
       }
    };
    Tab1D<long> tab1Dl( L , C , tab2D ); // création d'un 1D de long à partir d'un 2D
    Tab1D<double> tab1Dd( L , C , tab2D ); // création d'un 1D de double à partir d'un 2D

  3. #3
    Membre chevronné
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    avril 2016
    Messages
    447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : avril 2016
    Messages : 447
    Points : 1 953
    Points
    1 953

    Par défaut

    Bonjour,

    Citation Envoyé par NGeVtC87 Voir le message
    Aussi je veux pouvoir copier dans un tableau 1D de types différents (double, int, short int).
    Ce genre de factorisation se fait avec un template. En voici un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template<class Tab2D, class Index, class OutputIt>
    void copyTab2D(Tab2D tab2D, Index dim1, Index dim2, OutputIt out)
    {
    	for(Index i = 0; i < dim1; ++i) {
    		for(Index j = 0; j < dim2; ++j) {
    			*out = tab2D[i][j];
    			++out;
    		}
    	}
    }
    Et voici un bout de code qui l'utilise :
    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
    // Construction de tab2D.
    const size_t dim1 = 2;
    const size_t dim2 = 3;
    const double tab1[dim2] = {1.0, 3.0, 5.0};
    const double tab2[dim2] = {1.7, 3.7, 5.7};
    const double* const tab2D[dim1] = {tab1, tab2};
     
    // Construction de tab1D.
    double tab1D[dim1*dim2];
    copyTab2D(tab2D, dim1, dim2, tab1D);
     
    // Affichage de tab1D.
    std::cout << "Contenu de tab1D : ";
    for(size_t k = 0; k < dim1*dim2; ++k)
    	std::cout << tab1D[k] << " ; ";
    std::cout << '\n';
    Le code marche aussi si tu remplaces double par un autre type.

    A part ça, je ne sais pas où tu en es dans l'apprentissage des templates, donc j'en parle probablement trop tôt, mais, dans copyTab2D, out est un itérateur de sortie. Les itérateurs peuvent être des pointeurs, mais peuvent aussi être autre chose, ce qui rend très génériques les templates qui utilisent les itérateurs.
    Par exemple, copyTab2D peut être utilisé pour remplir un std::vector de cette manière :
    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
    // Construction de tab2D.
    const size_t dim1 = 2;
    const size_t dim2 = 3;
    const int tab1[dim2] = {10, 30, 50};
    const int tab2[dim2] = {17, 37, 57};
    const int* const tab2D[dim1] = {tab1, tab2};
     
    // Construction de monVecteur.
    std::vector<int> monVecteur;
    copyTab2D(tab2D, dim1, dim2, std::back_inserter(monVecteur));
     
    // Affichage de monVecteur.
    std::cout << "Contenu de monVecteur : ";
    for(double valeur : monVecteur)
    	std::cout << valeur << " ; ";
    std::cout << '\n';
    Ici, std::back_inserter(monVecteur) n'est pas un pointeur, mais un itérateur un peu spécial qui sert à remplir monVecteur. Avec cet itérateur, *out = tab2D[i][j] devient monVecteur.push_back(tab2D[i][j]) et ++out n'a aucun effet.

    Remarques diverses :
    • Pour la gestion de la mémoire, en C++, il faut éviter d'allouer des tableaux avec new. Il vaut mieux privilégier std::vector.
    • Dans mon code, tu as dû remarqué que j'ai alloué plein de tableaux dans la pile. J'ai utilisé des tableaux natifs du C++ mais, normalement, il aurait mieux valu utiliser std::array qui a l'avantage d'avoir une syntaxe similaire à celles des autres conteneurs de la bibliothèque standard.
    • Dans du code C++ bien fait, on a peu de chances de rencontrer des pointeurs de pointeurs.

Discussions similaires

  1. copier tableau d'entier /pointeur tableau entier
    Par darkman13130 dans le forum C++Builder
    Réponses: 4
    Dernier message: 10/10/2008, 09h33
  2. Tableau dynamique de pointeurs sur const char*
    Par Le Mérovingien dans le forum Débuter
    Réponses: 6
    Dernier message: 05/06/2008, 14h23
  3. lire un tableau grace à un pointeur
    Par Linu6 dans le forum Débuter
    Réponses: 5
    Dernier message: 22/09/2007, 15h48
  4. Réponses: 8
    Dernier message: 11/03/2007, 18h10
  5. Tableau 2 dimentions, pointeur
    Par DidierMesenbourg dans le forum C
    Réponses: 4
    Dernier message: 22/02/2005, 08h08

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