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 :

Allocation dynamique de tableau de dimensions variables


Sujet :

C++

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 106
    Points : 110
    Points
    110
    Par défaut Allocation dynamique de tableau de dimensions variables
    Bonjour;
    Je cherche à allouer dynamiquement un tableau dont toutes les dimensions sont variables. Pour un tableau dont seul le nombre de lignes varie, je procède comme suit:
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    int main()
    {
    	int k;
    	float x;	 
    	int cpt=0;	//Compteur de colonnes
    	int cpt1 = 0;//compteur de lignes
     
    	ifstream data("D:\\SignauxTexte\\donnes.txt",ios::in);
    	cout<<"donner une valeur: ";
    	cin>>k;
    	float (*Matrice)[100] =new float[k][100]; //Matrice de k lignes de 100 colonnes
    	while(true)
       {
       data >> x; 
       // test si fin de fichier atteinte
       if(data.eof() == true)
          break; 	
    	if(k!=0)
    	{	
    		if(cpt>=100){cpt=0;} // réinitialisation du compteur de colonnes
    		else
    		{
    			if(cpt1<k)
    			{
    			Matrice[cpt1][cpt] = x; //Remplissage de la matrice
    			cout<<"["<<cpt1<<" "<<cpt<<"]"<<" "<<Matrice[cpt1][cpt]<<endl;
    			cpt++;
    			if(cpt==99){cpt1++;}
    			}
     
    		}
     
     
    	}
     
    	}
    	delete[] Matrice;
    	return 0;
     
    }
    Maintenant je souhaite entrer la seconde dimension de mon tableau comme la première au clavier. J'ai lu des cours où on dit qu'il faut utiliser un tableau de pointeurs mais je ne sais pas comment procéder (je ne m'en sors pas avec les pointeurs). je voulais aussi savoir comment est-ce possible de faire varier le nombre de colonnes en gardant celui des lignes fixe.
    D'avance merci pour votre aide.

  2. #2
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 279
    Points : 11 015
    Points
    11 015
    Par défaut

  3. #3
    Membre habitué Avatar de SmOkEiSBaD
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    234
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Avril 2008
    Messages : 234
    Points : 127
    Points
    127
    Par défaut
    Jette un coup d'oeil à la FAQ, sinon sur internet tu doit trouver des exemples de Matrices dynamiques.

    Pour déclarer un tableau de pointeur tu rajoute une étoile.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    float * Matrice ou float Matrice[] //Tableau de float
    float ** Matrice ou float * Matrice[] ou float Matrice[][] //Tableau de pointeurs sur float

  4. #4
    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
    Points : 4 625
    Points
    4 625
    Par défaut
    boost multi_array

  5. #5
    Membre habitué Avatar de SmOkEiSBaD
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    234
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Avril 2008
    Messages : 234
    Points : 127
    Points
    127
    Par défaut
    Citation Envoyé par loufoque Voir le message
    boost multi_array
    Pourquoi faire simple quand on peut faire compliquer ?

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    Par défaut
    Salut,

    De manière générale, il faut éviter le recours à l'allocation dynamique si tu peux faire autrement... ou, du moins, laisser les classes dont on peut partir du principe qu'elles la gère mieux que toi s'en occuper.

    Alors qu'il n'y a pas le choix en C, le C++ fournit une série de conteneurs dont on est sur que la gestion de la mémoire les concernant se fera parfaitement.

    L'idée est donc de n'utiliser l'allocation dynamique de la mémoire que lorsqu'il s'agit de créer une instance d'une classe donnée alors que le pointeur que l'on utilise est du type d'une classe de base (pour implémenter le polymorphisme, principalement )...ou en cas d'absolue nécessité

  7. #7
    Membre régulier
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 106
    Points : 110
    Points
    110
    Par défaut
    Merci pour vos éléments de réponse

    Citation Envoyé par koala01 Voir le message
    Salut,
    Alors qu'il n'y a pas le choix en C, le C++ fournit une série de conteneurs dont on est sur que la gestion de la mémoire les concernant se fera parfaitement.
    L'idée est donc de n'utiliser l'allocation dynamique de la mémoire que lorsqu'il s'agit de créer une instance d'une classe donnée alors que le pointeur que l'on utilise est du type d'une classe de base (pour implémenter le polymorphisme, principalement )...ou en cas d'absolue nécessité
    Voilà ce que je veux faire exactement : Je souhaite fixer le nombre de lignes à considérer de façon manuelle. Par contre la seconde dimension, le nombre de colonnes sera le résultat d'une opération. Donc lorsque j'ai ce résultat pour la première fois, j'alloue mon tableau[n lignes][ncolonnes]. A partir de cet instant, je remplis mon tableau avec des donnes contenues dans des tableaux de dimension 1, dont la taille n'est pas fixe. Alors je complète avec des zeros ou je tronque ce dernier suivant que sa taille est plus grande que ncolonnes. Lorsque le resulat de mon opération change, alors je ré alloue un nouveau tableau avec cette nouvelle valeur dans lequel je copie les données de l'ancien tableau en les tronquant ou en les complétant avec des zéros. Un exemple de calcul du nombre de colonnes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    void DefineTaille(int freq, int moyenne)
    {
    	const int TMin=50, TMax=150;
    	int Taille, indice;
    	indice= (int) round(60*freq/moyenne,0);
     
    	if(indice  < TMin)
    	{
    		Taille = TMin;
    	}
    	else{Taille =(TMin +TMax)/2;}
    }
    Je me pose la question de la faisabilité de ce genre de tableau. Existe-t-il des conteneurs ou des méthodes qui permettent de faire des manipulations de ce type?

  8. #8
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Citation Envoyé par SmOkEiSBaD Voir le message
    Pourquoi faire simple quand on peut faire compliquer ?
    Parce que ce que tu crois simple n'est nullement robuste ? (tu verrais vite à quel point ce n'est pas trivial sinon)

    @OP, boost.multi_array, stlsoft.array2D, etc. Les choix ne manquent pas.

  9. #9
    Membre confirmé

    Inscrit en
    Août 2007
    Messages
    300
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 300
    Points : 527
    Points
    527
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Parce que ce que tu crois simple n'est nullement robuste ? (tu verrais vite à quel point ce n'est pas trivial sinon)

    @OP, boost.multi_array, stlsoft.array2D, etc. Les choix ne manquent pas.
    Je pense que le commentaire de SmOkEiSBaD s'appliquait spécifiquement à boost::multi_array, par opposition aux très nombreux autres moyens robustes de faire des tableaux multidimensionnels en C++ (comme vous dites, le choix est vaste).
    Alors que la qualité générale de boost est exceptionnelle, il faut bien reconnaitre que boost::multi_array détonne franchement, et serait probablement refusée si elle était proposée aujourd'hui pour inclusion dans boost. Malgré l'évident besoin d'une bonne librairie standard pour les tableaux multi-dimensionnels en C++, et malgré le fait que bien des ajouts à la librairie standard de C++ proviennent pratiquement directement de boost, je veux bien parier que jamais boost::multi_array ne sera admise au standard (et c'est tant mieux).

  10. #10
    Membre régulier
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 106
    Points : 110
    Points
    110
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Parce que ce que tu crois simple n'est nullement robuste ? (tu verrais vite à quel point ce n'est pas trivial sinon)

    @OP, boost.multi_array, stlsoft.array2D, etc. Les choix ne manquent pas.
    En fait, je cherche effectivement à faire quelque chose de très simple et j'aimerais éviter au maximum les trucs très compliqués. J'ai trouvé des exemples sur FAQ et j'ai procédé comme suit:
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    int main()
    {
    	int k,m;
    	int dim;
    	float x,maximum;	 
    	int cpt=0;	//Compteur de colonnes
    	int cpt1 = 0;//compteur de lignes
    	ifstream data("D:\\SignauxTexte\\donnes.txt",ios::in);
    	cout<<"nombre de lignes: ";
    	cin>>k;
    	cout<<"nombre de colonnes: ";
    	cin>>m;
    	float **Matrice=0; 
    	Matrice = new float *[m];  
    	for(dim=0; dim<k;dim++){Matrice[dim]=new float[dim];}
    	while(true)
       {
       data >> x; 
       // test si fin de fichier atteinte
       if(data.eof() == true)
          break; 	
    	if(k!=0)
    	{	
    		if(cpt>=m){cpt=0;} // reunitialisation du compteur de colonnes
    		else
    		{
    			if(cpt1<k)
    			{
    			Matrice[cpt1][cpt] = x; //Remplissage de la matrice
    			cout<<"["<<cpt1<<" "<<cpt<<"]"<<" "<<Matrice[cpt1][cpt]<<endl;			
    			if(cpt==m-1){cpt1++;}
    			cpt++;
    			}
     
    		}
     
     
    	}
     
    	}
     
    	return 0;
     
    }
    Lorsque je lance l'exécution de mon programme en prenant par exemple 5 et 100, mon programme s'arrête à 60 maximum. Donc mon tableau ne se remplit pas correctement. je ne sais pas ce qui ne va pas.
    A la compilation, il n'y a pas de problèmes.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    Par défaut
    Mais, pourquoi demander à l'utilisateur d'introduire le nombre de ligne et de colonnes ... autant laisser la lecture du fichier s'en charger

    En outre, la classe vector, disponible dans l'espace de noms std par inclusion du fichier d'en-tête <vector> te permet de gérer cela sans aucun problème... et sans avoir à t'inquiéter de l'allocation dynamique

    Si tu rajoute la classe stringstream, disponible également dans l'espace de noms std, mais par insertion du fichier d'en-tête <sstream>, tu as tout ce dont tu peux avoir besoin

    En gros, tu choisis une manière compliquée et loin d'être robuste pour faire quelque chose que quelques lignes de code suffiraient à réaliser, si tu prenais la peine d'utiliser les classes qui vont bien

    Et le code permettant de gérer tout cela pourrait très bien ressembler à
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    #include <fstream> // pour la classe ifstream
    #include <sstream> // pour la classe stringstram
    #include <vector>  // pour la classe vector
    #include <iostream> // pour disposer de cout
    #include <string>  // pour la classe string
    int main()
    {
        /* ouvrons le fichier en lecture */
        std::ifstream data("D:\\SignauxTexte\\donnes.txt");
        /*il nous faut un vecteur de vecteurs */
        std::vector<std::vector<float> > matrice;
        /* par sécurité, assurons nous que le fichier a pu être ouvert */
        if(data)
        {
            /* il nous faut une chaine de caractères permettant de récupérer
             * la ligne entière
             */
            std::string str;
            /* bouclons tant qu'il y a moyen de lire une ligne */
            while(std::getline(data,str))
            {
                /* une chaine, c'est bien, mais on souhaite travailler sur des réels
                 * un flux de conversion et une variable de type réel s'imposent
                 */
                float temp;
                std::stringstream ss;
                /* plaçons la chaine lue dans le flux de conversion */
                ss<<str;
                /* il nous faut un tableau (vecteur) de colones (qui contient des
                 * réels) qui représente la ligne
                 */
                std::vector< float> ligne;
                /* tant que nous récupérons un réel du flux de conversion, nous
                 * le rajoutons sous la forme d'une cellule
                 */
                while(ss>>temp)
                {
                    ligne.push_back(temp);
                }
                /* Quand la ligne est finie, nous l'insérons dans la matrice */
                matrice.push_back(ligne);
            }
        }
        else
        {
            /* je n'ai cure de la raison pour laquelle le  fichier n'est pas ouvert */
            std::cout<<"ouverture du fichier impossible"<<std::endl;
        }
        /*allez, pour faire bien, vérifions si la matrice n'est pas vide */
        if(matrice.size()<0)
        {
            /* et gérons son contenu ici */
        }
        /* nous avons fini, l'application peut s'arrêter */
        return 0;
    }
    Si ce code te parait long, c'est surtout parce qu'il y a 22 lignes (sur 56) qui ne sont que des commentaires et 5 lignes "mixtes (code + commentaires)", qu'il te serait intéressant de lire, et que j'ai suivi des règles d'intentation et de retour à la ligne strictes

  12. #12
    Membre régulier
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 106
    Points : 110
    Points
    110
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Mais, pourquoi demander à l'utilisateur d'introduire le nombre de ligne et de colonnes ... autant laisser la lecture du fichier s'en charger
    Merci beau coup pour votre aide;
    Mon idée était de pouvoir découper et de ranger dans des matrices des données en fonctions de certains critères. J'ai juste une seule colonne dans mon fichier. C'est pourquoi je voudrais que l'utilisateur puisse définir la taille de la matrice. Mais en suivant votre méthode j'y suis arrivé. Encore merci et bonne soirée.

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 12/06/2007, 14h15
  2. [débutant] un tableau de dimension variable selon l'objet qui le contient
    Par Epistocles dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 09/01/2007, 18h07
  3. Réponses: 2
    Dernier message: 14/12/2006, 15h34
  4. Réponses: 6
    Dernier message: 26/11/2005, 19h55
  5. Réponses: 4
    Dernier message: 03/12/2002, 16h47

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