|
Trouver une ressource
Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !
FONCTIONS DE STD::VECTOR
Information sur la source
Description
Ce code présente toutes les fonctions de std::vector et la spécialisation du vector<bool> Pas de manière complètement exhaustive, mais un bon aperçu tout de même des possibilités de traitement d'un vecteur.
Source
- // INCLUDE
- #include <vector> // Inclue la classe vector
- #include <iostream> // Pour l'utilisation de cout
- #include <cassert> // Pour les assertions
- #include <valarray> // Pour comparer un vecteur de booléen avec un valarray de booléen
-
- // PROTOTYPE
- void afficher(const std::vector<int>& VecteurAafficher); // Fonction d'affichage de vecteur sur std::cout
- void reinitialiser(std::vector<int>& VecteurAinitialiser); // Réinitialise le vecteur avec des valeurs prédéfinies
-
-
- // MAIN
- void main()
- {
- std::vector<int> MonVecteur; // Déclaration de mon vecteur comme un vecteur d'entiers
- reinitialiser(MonVecteur);
- afficher(MonVecteur);
-
- std::vector<int> MonVecteur2; // Déclaration de mon vecteur comme un vecteur d'entiers
- MonVecteur2.push_back(43500);
- MonVecteur2.push_back(4);
- MonVecteur2.push_back(36);
-
-
- // OPERATEUR [] (fonction membre operator []))
- // (1) Assigne une référence sur un élément du vecteur
- // (2) Assigne une référence constante sur un élément du vecteur
- std::cout << "[] (1)" << std::endl;
- int &element2=MonVecteur[1]; // Une fois la référence obtenue, j'ai accès en lecture/écriture à cet élément du vecteur
- std::cout << "Deuxieme element du vecteur est " << element2 << std::endl;
- element2=4810; // Ayant obtenu une référence, toute modification sur la référence s'applique au deuxième élément du vecteur
- afficher(MonVecteur);
- MonVecteur[2]=2981; // Je peux aussi directement attribué une valeur à un élément du vecteur, comme pour un tableau
- afficher(MonVecteur);
- MonVecteur.operator [](2)=2086; // Cette expression permet de mieux voir [] comme une fonction membre (juste pour la remarque)
- afficher(MonVecteur);
- reinitialiser(MonVecteur);
- std::cout << "[] (2)" << std::endl; // Nous obtenons maintenant une référence constante : nous avons un accès en lecture seule
- const int &element1=MonVecteur[0]; // Le simple fait de mettre const fait comprendre au compilateur de renvoyer une référence constante
- std::cout << "Premier element du vecteur est " << element1 << std::endl;
- // element1=4102; // lecture seule : pas de compilation de cette ligne
- // Se reporter aux commentaires d'Hylvenir
-
-
- // FONCTION ASSIGN
- // (1) Efface le contenu du vecteur et lui attribue celui d'un autre vector ou sous vector (compris entre les 2 itérateurs)
- // (2) Efface le contenu du vecteur et lui attribue une même valeur un certain nombre de fois
- std::cout << "ASSIGN (1)" << std::endl;
- MonVecteur.assign(MonVecteur2.begin(), MonVecteur2.end());
- afficher(MonVecteur);
- //MonVecteur.assign(MonVecteur2.end(), MonVecteur2.begin()); // Cas d'erreur (inversion des 2 itérateurs). Cette ligne provoque le "plantage" du programme.
- std::vector<int>::iterator Debut2=MonVecteur2.begin();
- Debut2++; // Debut2 est un pointeur sur le deuxième élément
- MonVecteur.assign(Debut2, MonVecteur2.end());
- afficher(MonVecteur);
- std::cout << "ASSIGN (2)" << std::endl;
- MonVecteur.assign(5,10); // Mettre la valeur "10" 5 fois dans le vecteur
- afficher(MonVecteur);
- reinitialiser(MonVecteur);
-
-
- // FONCTION AT
- // (1) Renvoie une référence sur un élément du vecteur
- // (2) Renvoie une référence constante sur un élément du vecteur
- std::cout << "AT (1)" << std::endl;
- int &monat=MonVecteur.at(2); // Récupère une référence sur le deuxième élément du vecteur
- std::cout << "3eme Element du vecteur : " << monat << std::endl;
- monat=74; // C'est une référence, si je modifie monat je modifie aussi l'élément correspondant du vecteur
- afficher(MonVecteur); // L'élément 2 du vecteur est passé à 74
- std::cout << "AT (2)" << std::endl;
- const int &monatconst=MonVecteur.at(0); // Récupère une référence constante
- //monatconst=1; // Je ne peux donc pas toucher à la valeur, cette ligne ne compile pas
- std::cout << "1er Element du vecteur : " << monatconst << std::endl;
- reinitialiser(MonVecteur);
-
-
- // FONCTION BACK
- // (1) Renvoie une référence modifiable sur le dernier élément
- // (2) Renvoie une référence non modifiable sur le dernier élément
- std::cout << "BACK (1)" << std::endl;
- int& i = MonVecteur.back( );
- std::cout << i << std::endl;
- i=999;
- afficher(MonVecteur); // A partir du moment où j'obtiens une référence modifiable, je modifie i et la modification se répercute sur le dernier élément du vecteur
- std::cout << "BACK (2)" << std::endl;
- const int& j = MonVecteur.back(); // Comme j'ai mis le mot clé const, je vais obtenir une référence non modifiable
- // j = 888; // -----> Je ne peux pas compiler cette ligne de code. j est en quelque sorte en lecture seule.
- // Si on ne veut pas modifier le dernier élément du vecteur on a intérêt à utiliser cette référence constante
- std::cout << j << std::endl;
- reinitialiser(MonVecteur);
-
-
- // FONCTION BEGIN
- // (1) Renvoie un itérateur modifiable sur le premier élémént
- // (2) Renvoie un itérateur non modifiable sur le premier élément
- std::cout << "BEGIN (1)" << std::endl;
- std::vector<int>::iterator UnIterateur; // Déclaration d'un itérateur sur un vecteur d'entiers
- UnIterateur = MonVecteur.begin(); // On lui attribue l'adresse du premier élément du vecteur
- std::cout << *UnIterateur << std::endl; // Affichage du contenu du pointeur
- *UnIterateur = 777; // Modification du premier élément
- std::cout << *UnIterateur << std::endl; // Affichage du contenu du pointeur
- UnIterateur++; // On pointe maintenant sur le deuxième élément
- std::cout << *UnIterateur << std::endl; // Affichage du contenu du pointeur
- std::cout << "BEGIN (2)" << std::endl;
- std::vector<int>::const_iterator UnIterateurConstant; // Déclaration d'un itérateur constant sur un vecteur d'entiers
- UnIterateurConstant = MonVecteur.begin();
- std::cout << *UnIterateurConstant << std::endl; // Affichage du contenu du pointeur
- // *UnIterateurConstant = 666; // ---> Ca ne compile pas, le contenu du pointeur est protégé
- UnIterateurConstant++; // Ca par contre, je peux. Je me balade donc sur les éléments du vecteur, sans pouvoir les modifier
- std::cout << *UnIterateurConstant << std::endl; // Affichage du contenu du pointeur
- reinitialiser(MonVecteur);
-
-
- // FONCTION CAPACITY
- // (1) Renvoie le nombre d'élément que le vecteur pourrait contenir sans allouer plus de mémoire
- std::cout << "CAPACITY (1)" << std::endl;
- std::cout << "Capacite de MonVecteur : " << MonVecteur.capacity() << std::endl;
- MonVecteur.reserve(20); // Je réserve 20 places pour mon vecteur
- std::cout << "Capacite de MonVecteur : " << MonVecteur.capacity() << std::endl;
- std::cout << "Taille de MonVecteur : " << MonVecteur.size() << std::endl; // On peut ainsi voir la différente entre size(), le nombre d'éléments réellement occupés et capacity, le nombre total d'éléments réservés au vecteur
- afficher(MonVecteur);
- reinitialiser(MonVecteur);
-
-
- // FONCTION CLEAR
- // Vide le vecteur
- std::cout << "CLEAR" << std::endl;
- MonVecteur.clear();
- afficher(MonVecteur);
- reinitialiser(MonVecteur);
-
-
- // FONCTION EMPTY
- // Dit si le vecteur est vide ou non
- std::cout << "EMPTY" << std::endl;
- if(MonVecteur.empty()!=true)
- std::cout << "Ce vecteur n'est pas vide" << std::endl;
- MonVecteur.clear();
- if(MonVecteur.empty()==true)
- std::cout << "Ce vecteur est vide (on vient de faire un clear)" << std::endl;
- reinitialiser(MonVecteur);
-
-
- // FONCTION END
- // Equivalent de BEGIN pour la fin du vecteur ; attention end() pointe après le dernier élément du vecteur
-
-
- // FONCTION ERASE
- // (1) Efface un élément
- // (2) Efface une série d'éléments
- std::cout << "ERASE (1)" << std::endl;
- MonVecteur.erase(MonVecteur.begin()); // Efface le premier élément
- afficher(MonVecteur);
- reinitialiser(MonVecteur);
- std::cout << "ERASE (2)" << std::endl;
- MonVecteur.erase(MonVecteur.begin(),MonVecteur.end()); // Efface du premier au dernier élément (équivalent d'un clear)
- afficher(MonVecteur);
- reinitialiser(MonVecteur);
-
-
- // FONCTION FRONT
- // Equivalent BACK pour le début du vecteur
-
-
- // GET_ALLOCATOR
- // Récupère le système d'allocation utilisée par un vecteur pour par exemple fabriquer un nouveau vecteur sur la base de cette allocation
- std::cout << "GET_ALLOCATOR" << std::endl;
- std::vector<int> vecteurAllocationCommeMonVecteur(MonVecteur.get_allocator() );
- std::vector<double> Unvecteuravecuneautreallocation;
- if(Unvecteuravecuneautreallocation.get_allocator().max_size()!=MonVecteur.get_allocator().max_size())
- std::cout << "espace maximale alloue par int et double est different !" << std::endl;
-
-
- // INSERT
- // Insère de nouveaux éléments dans le vecteur
- std::cout << "INSERT (1)" << std::endl;
- std::vector<int>::iterator IteEndroitInsere=MonVecteur.end();
- IteEndroitInsere--; // On va insérer le nouvel élément à l'avant dernière position
- MonVecteur.insert(IteEndroitInsere,42);
- afficher(MonVecteur);
- std::cout << "INSERT (2)" << std::endl;
- IteEndroitInsere=MonVecteur.begin();
- MonVecteur.insert(IteEndroitInsere+2,4,1); // On insère 4 fois 1 au niveau de l'itérateur IteEndroitInsere
- afficher(MonVecteur);
- std::cout << "INSERT (3)" << std::endl;
- IteEndroitInsere=MonVecteur.begin();
- MonVecteur.insert(IteEndroitInsere+4,MonVecteur2.begin(),--MonVecteur2.end()); // On insère tous les éléments du vecteur 2 sauf le dernier au niveau de l'itérateur IdeEndroitInsere
- afficher(MonVecteur);
- reinitialiser(MonVecteur);
-
-
- // MAX_SIZE
- // Renvoie la taille maximale que peut prendre le vecteur
- std::cout << "MAX_SIZE" << std::endl;
- std::cout << "Taille maximale du vecteur : " << MonVecteur.max_size() << std::endl;
-
-
- // POP_BACK
- // Efface le dernier élément du vecteur
- afficher(MonVecteur);
- MonVecteur.pop_back();
- afficher(MonVecteur);
- reinitialiser(MonVecteur);
-
-
- // PUSH_BACK
- // Insère un élément à la dernière position du vecteur
- afficher(MonVecteur);
- MonVecteur.push_back(42);
- afficher(MonVecteur);
- reinitialiser(MonVecteur);
-
-
- // RBEGIN
- // Permet de parcourir le vecteur inversé
- // (1) Renvoie un itérateur modifiable sur le premier élémént du vecteur inversé
- // (2) Renvoie un itérateur non modifiable sur le premier élément
- std::cout << "RBEGIN (1)" << std::endl;
- std::vector<int>::reverse_iterator UnRIterateur; // Déclaration d'un reverse itérateur sur un vecteur d'entiers
- UnRIterateur = MonVecteur.rbegin(); // On lui attribue l'adresse du premier élément du vecteur inversé
- std::cout << *UnRIterateur << std::endl; // Affichage du contenu du pointeur
- *UnRIterateur = 777; // Modification du premier élément
- std::cout << *UnRIterateur << std::endl; // Affichage du contenu du pointeur
- UnRIterateur++; // On pointe maintenant sur le deuxième élément
- std::cout << *UnRIterateur << std::endl; // Affichage du contenu du pointeur
- reinitialiser(MonVecteur);
- std::cout << "RBEGIN (2)" << std::endl;
- std::vector<int>::const_reverse_iterator UnRIterateurConstant; // Déclaration d'un itérateur constant sur un vecteur d'entiers
- UnRIterateurConstant = MonVecteur.rbegin();
- std::cout << *UnRIterateurConstant << std::endl; // Affichage du contenu du pointeur
- // *UnRIterateurConstant = 666; //---> Ca ne compile pas, le contenu du pointeur est protégé
- UnRIterateurConstant++; // Ca par contre, je peux. Je me balade donc sur les éléments du vecteur inversé, sans pouvoir les modifier
- std::cout << *UnRIterateurConstant << std::endl; // Affichage du contenu du pointeur
- reinitialiser(MonVecteur);
-
-
- // REND
- // Permet de parcourir le vecteur inversé en fournissant un pointeur après le dernier élément du vecteur
- // (1) Renvoie un itérateur modifiable sur le dernier élémént du vecteur inversé
- // (2) Renvoie un itérateur non modifiable sur le dernier élément
- std::cout << "REND (1)" << std::endl;
- std::vector<int>::reverse_iterator UnRIterateurEnd; // Déclaration d'un reverse itérateur sur un vecteur d'entiers
- UnRIterateurEnd = MonVecteur.rend(); // On lui attribue l'adresse du premier élément du vecteur inversé
- std::cout << *UnRIterateurEnd << std::endl; // Affichage du contenu du pointeur : rend une valeur "fausse" puisque nous sommes en dehors du vecteur inversé
- UnRIterateurEnd--; // Modification du dernier élément (du vecteur inversé)
- std::cout << *UnRIterateurEnd << std::endl; // Affichage du contenu du pointeur
- UnRIterateurEnd--; // On pointe maintenant sur le deuxième élément
- std::cout << *UnRIterateurEnd << std::endl; // Affichage du contenu du pointeur
- UnRIterateurEnd--; // On pointe maintenant sur le troisième et dernier élément
- std::cout << *UnRIterateurEnd << std::endl; // Affichage du contenu du pointeur
- reinitialiser(MonVecteur);
- std::cout << "REND (2)" << std::endl;
- std::vector<int>::const_reverse_iterator UnRIterateurConstantEnd; // Déclaration d'un itérateur constant sur un vecteur d'entiers
- UnRIterateurConstantEnd = MonVecteur.rend();
- UnRIterateurConstantEnd--;
- std::cout << *UnRIterateurConstantEnd << std::endl; // Affichage du contenu du pointeur
- // *UnRIterateurConstant = 666; //---> Ca ne compile pas, le contenu du pointeur est protégé
- UnRIterateurConstantEnd--; // Ca par contre, je peux. Je me balade donc sur les éléments du vecteur inversé, sans pouvoir les modifier
- std::cout << *UnRIterateurConstantEnd << std::endl; // Affichage du contenu du pointeur
- reinitialiser(MonVecteur);
-
-
- // RESERVE
- // Réserve de la place pour le vecteur
- std::cout << "RESERVE (1)" << std::endl;
- MonVecteur.reserve(20); // Je réserve 20 places pour mon vecteur (voir la fonction capacity)
- afficher(MonVecteur);
- reinitialiser(MonVecteur);
-
-
- // RESIZE
- // Redéfinit la taille du vecteur
- // (1) En indiquant la nouvelle taille
- // (2) En indiquant la nouvelle taille et la valeur des éléments à ajouter le cas échéant
- std::cout << "RESIZE (1)" << std::endl;
- MonVecteur.resize(10); // Nouvelle taille du vecteur : 10
- afficher(MonVecteur);
- MonVecteur.resize(2);
- afficher(MonVecteur);
- std::cout << "RESIZE (2)" << std::endl;
- MonVecteur.resize(10,67);
- afficher(MonVecteur);
- MonVecteur.resize(4,68); // Deuxième paramètre superflu, puisque la nouvelle taille impose une réduction du vecteur
- afficher(MonVecteur);
- reinitialiser(MonVecteur);
-
-
- // SIZE
- // Renvoie la taille du vecteur
- std::cout << "SIZE (1)" << std::endl;
- std::cout << "La taille de MonVecteur est : " << MonVecteur.size() << std::endl;
-
-
- // SWAP
- // (1) Echange les éléments de deux vecteurs
- // (2) Echange les éléments de deux vecteurs (fonction amie)
- std::cout << "SWAP (1)" << std::endl;
- MonVecteur2.clear();
- MonVecteur2.push_back(90); // Remplissage de MonVecteur2
- MonVecteur2.push_back(25);
- MonVecteur2.push_back(39);
- MonVecteur2.push_back(70);
- MonVecteur.swap(MonVecteur2);
- afficher(MonVecteur);
- std::cout << "SWAP (2)" << std::endl;
- swap(MonVecteur,MonVecteur2);
- afficher(MonVecteur);
-
- // SPECIALISATION DU VECTEUR DANS LE CAS DE BOOLEENS
- // Un booléen du vecteur va être stocké sur un bit au lieu d'être stocké sur un octet
- // Pour vérifier cela, nous allons comparer la capacité d'un vecteur de booléens
- // et celle d'un vecteur de char (un char tenant sur un bit)
- std::cout << "Specialisation du vecteur dans le cas de booleens" << std::endl;
- std::vector<bool> VecteurLogique;
- std::vector<char> VecteurChar;
- VecteurLogique.push_back(true);
- VecteurChar.push_back('c');
-
- std::cout << "Capacite vecteur logique : " << VecteurLogique.capacity() << std::endl;
- std::cout << "Capacite vecteur char : " << VecteurChar.capacity() << std::endl;
- // Avec l'affichage ci-dessus, nous remarquons que la capacité du vecteur logique est bien supérieure à celle du char
- // Typiquement celle du bool est de 32 et celle du char de 1
-
- VecteurLogique.push_back(true);
- VecteurChar.push_back('c');
-
- std::cout << "Capacite vecteur logique : " << VecteurLogique.capacity() << std::endl;
- std::cout << "Capacite vecteur char : " << VecteurChar.capacity() << std::endl;
- // L'ajout d'un bool ne modifie pas la capacité toujours à 32
-
- for(int ind=0;ind<30;ind++)
- {
- VecteurLogique.push_back(true);
- VecteurChar.push_back('c');
- }
- // Je complète le vecteur logique pour qu'il ait 32 valeurs (nous en avions déjà 2, je lui en mets 30 supplémentaires)
-
- std::cout << "Capacite vecteur logique : " << VecteurLogique.capacity() << std::endl;
- std::cout << "Capacite vecteur char : " << VecteurChar.capacity() << std::endl;
- // La capacité du vecteur logique est atteinte...
-
- VecteurLogique.push_back(true);
- VecteurChar.push_back('c');
-
- // En rajoutant un élément, je la fais basculer à 64 (le bit "débordant" a provoqué l'allocation d'un nouvel octet de 32 bits où peuvent potentiellement être stockés 32 booléens)
- std::cout << "Capacite vecteur logique : " << VecteurLogique.capacity() << std::endl;
- std::cout << "Capacite vecteur char : " << VecteurChar.capacity() << std::endl;
-
- // La spécialisation de vector<bool> représente donc un gain de places
- // Voir la contre partie en lisant les commentaires de steve_clamage
- }
-
-
- // AFFICHER
- // Affiche tous les éléments de MonVecteur
- void afficher(const std::vector<int> &VecteurAafficher)
- {
- std::cout << "***" << std::endl;
- if(!VecteurAafficher.empty())
- {
- std::vector<int>::const_iterator Iterateurvecteur; // Construction d'un itérateur pour parcourir les éléments du vecteur
- for(Iterateurvecteur=VecteurAafficher.begin();Iterateurvecteur!=VecteurAafficher.end();Iterateurvecteur++)
- {
- std::cout << "Valeur de l'iterateur : " << (*Iterateurvecteur) << std::endl; // L'itérateur est un pointeur sur un élément du vecteur. Pour avoir son contenu il faut donc mettre la petite étoile devant.
- }
-
- }
- else
- {
- std::cout << "le vecteur est vide" << std::endl;
- }
- std::cout << "***" << std::endl;
- }
-
-
- // REINITIALISER
- // Réinitialise le vecteur avec une série de nombre
- void reinitialiser(std::vector<int> &VecteurAinitialiser)
- {
- VecteurAinitialiser.clear();
- VecteurAinitialiser.push_back(38); // On remplit le vecteur avec différents éléments par des "push_back"
- VecteurAinitialiser.push_back(26); // Chaque push_back ajoute un élément à le vecteur en le plaçant à la dernière position
- VecteurAinitialiser.push_back(73);
- }
-
-
-
// INCLUDE
#include <vector> // Inclue la classe vector
#include <iostream> // Pour l'utilisation de cout
#include <cassert> // Pour les assertions
#include <valarray> // Pour comparer un vecteur de booléen avec un valarray de booléen
// PROTOTYPE
void afficher(const std::vector<int>& VecteurAafficher); // Fonction d'affichage de vecteur sur std::cout
void reinitialiser(std::vector<int>& VecteurAinitialiser); // Réinitialise le vecteur avec des valeurs prédéfinies
// MAIN
void main()
{
std::vector<int> MonVecteur; // Déclaration de mon vecteur comme un vecteur d'entiers
reinitialiser(MonVecteur);
afficher(MonVecteur);
std::vector<int> MonVecteur2; // Déclaration de mon vecteur comme un vecteur d'entiers
MonVecteur2.push_back(43500);
MonVecteur2.push_back(4);
MonVecteur2.push_back(36);
// OPERATEUR [] (fonction membre operator []))
// (1) Assigne une référence sur un élément du vecteur
// (2) Assigne une référence constante sur un élément du vecteur
std::cout << "[] (1)" << std::endl;
int &element2=MonVecteur[1]; // Une fois la référence obtenue, j'ai accès en lecture/écriture à cet élément du vecteur
std::cout << "Deuxieme element du vecteur est " << element2 << std::endl;
element2=4810; // Ayant obtenu une référence, toute modification sur la référence s'applique au deuxième élément du vecteur
afficher(MonVecteur);
MonVecteur[2]=2981; // Je peux aussi directement attribué une valeur à un élément du vecteur, comme pour un tableau
afficher(MonVecteur);
MonVecteur.operator [](2)=2086; // Cette expression permet de mieux voir [] comme une fonction membre (juste pour la remarque)
afficher(MonVecteur);
reinitialiser(MonVecteur);
std::cout << "[] (2)" << std::endl; // Nous obtenons maintenant une référence constante : nous avons un accès en lecture seule
const int &element1=MonVecteur[0]; // Le simple fait de mettre const fait comprendre au compilateur de renvoyer une référence constante
std::cout << "Premier element du vecteur est " << element1 << std::endl;
// element1=4102; // lecture seule : pas de compilation de cette ligne
// Se reporter aux commentaires d'Hylvenir
// FONCTION ASSIGN
// (1) Efface le contenu du vecteur et lui attribue celui d'un autre vector ou sous vector (compris entre les 2 itérateurs)
// (2) Efface le contenu du vecteur et lui attribue une même valeur un certain nombre de fois
std::cout << "ASSIGN (1)" << std::endl;
MonVecteur.assign(MonVecteur2.begin(), MonVecteur2.end());
afficher(MonVecteur);
//MonVecteur.assign(MonVecteur2.end(), MonVecteur2.begin()); // Cas d'erreur (inversion des 2 itérateurs). Cette ligne provoque le "plantage" du programme.
std::vector<int>::iterator Debut2=MonVecteur2.begin();
Debut2++; // Debut2 est un pointeur sur le deuxième élément
MonVecteur.assign(Debut2, MonVecteur2.end());
afficher(MonVecteur);
std::cout << "ASSIGN (2)" << std::endl;
MonVecteur.assign(5,10); // Mettre la valeur "10" 5 fois dans le vecteur
afficher(MonVecteur);
reinitialiser(MonVecteur);
// FONCTION AT
// (1) Renvoie une référence sur un élément du vecteur
// (2) Renvoie une référence constante sur un élément du vecteur
std::cout << "AT (1)" << std::endl;
int &monat=MonVecteur.at(2); // Récupère une référence sur le deuxième élément du vecteur
std::cout << "3eme Element du vecteur : " << monat << std::endl;
monat=74; // C'est une référence, si je modifie monat je modifie aussi l'élément correspondant du vecteur
afficher(MonVecteur); // L'élément 2 du vecteur est passé à 74
std::cout << "AT (2)" << std::endl;
const int &monatconst=MonVecteur.at(0); // Récupère une référence constante
//monatconst=1; // Je ne peux donc pas toucher à la valeur, cette ligne ne compile pas
std::cout << "1er Element du vecteur : " << monatconst << std::endl;
reinitialiser(MonVecteur);
// FONCTION BACK
// (1) Renvoie une référence modifiable sur le dernier élément
// (2) Renvoie une référence non modifiable sur le dernier élément
std::cout << "BACK (1)" << std::endl;
int& i = MonVecteur.back( );
std::cout << i << std::endl;
i=999;
afficher(MonVecteur); // A partir du moment où j'obtiens une référence modifiable, je modifie i et la modification se répercute sur le dernier élément du vecteur
std::cout << "BACK (2)" << std::endl;
const int& j = MonVecteur.back(); // Comme j'ai mis le mot clé const, je vais obtenir une référence non modifiable
// j = 888; // -----> Je ne peux pas compiler cette ligne de code. j est en quelque sorte en lecture seule.
// Si on ne veut pas modifier le dernier élément du vecteur on a intérêt à utiliser cette référence constante
std::cout << j << std::endl;
reinitialiser(MonVecteur);
// FONCTION BEGIN
// (1) Renvoie un itérateur modifiable sur le premier élémént
// (2) Renvoie un itérateur non modifiable sur le premier élément
std::cout << "BEGIN (1)" << std::endl;
std::vector<int>::iterator UnIterateur; // Déclaration d'un itérateur sur un vecteur d'entiers
UnIterateur = MonVecteur.begin(); // On lui attribue l'adresse du premier élément du vecteur
std::cout << *UnIterateur << std::endl; // Affichage du contenu du pointeur
*UnIterateur = 777; // Modification du premier élément
std::cout << *UnIterateur << std::endl; // Affichage du contenu du pointeur
UnIterateur++; // On pointe maintenant sur le deuxième élément
std::cout << *UnIterateur << std::endl; // Affichage du contenu du pointeur
std::cout << "BEGIN (2)" << std::endl;
std::vector<int>::const_iterator UnIterateurConstant; // Déclaration d'un itérateur constant sur un vecteur d'entiers
UnIterateurConstant = MonVecteur.begin();
std::cout << *UnIterateurConstant << std::endl; // Affichage du contenu du pointeur
// *UnIterateurConstant = 666; // ---> Ca ne compile pas, le contenu du pointeur est protégé
UnIterateurConstant++; // Ca par contre, je peux. Je me balade donc sur les éléments du vecteur, sans pouvoir les modifier
std::cout << *UnIterateurConstant << std::endl; // Affichage du contenu du pointeur
reinitialiser(MonVecteur);
// FONCTION CAPACITY
// (1) Renvoie le nombre d'élément que le vecteur pourrait contenir sans allouer plus de mémoire
std::cout << "CAPACITY (1)" << std::endl;
std::cout << "Capacite de MonVecteur : " << MonVecteur.capacity() << std::endl;
MonVecteur.reserve(20); // Je réserve 20 places pour mon vecteur
std::cout << "Capacite de MonVecteur : " << MonVecteur.capacity() << std::endl;
std::cout << "Taille de MonVecteur : " << MonVecteur.size() << std::endl; // On peut ainsi voir la différente entre size(), le nombre d'éléments réellement occupés et capacity, le nombre total d'éléments réservés au vecteur
afficher(MonVecteur);
reinitialiser(MonVecteur);
// FONCTION CLEAR
// Vide le vecteur
std::cout << "CLEAR" << std::endl;
MonVecteur.clear();
afficher(MonVecteur);
reinitialiser(MonVecteur);
// FONCTION EMPTY
// Dit si le vecteur est vide ou non
std::cout << "EMPTY" << std::endl;
if(MonVecteur.empty()!=true)
std::cout << "Ce vecteur n'est pas vide" << std::endl;
MonVecteur.clear();
if(MonVecteur.empty()==true)
std::cout << "Ce vecteur est vide (on vient de faire un clear)" << std::endl;
reinitialiser(MonVecteur);
// FONCTION END
// Equivalent de BEGIN pour la fin du vecteur ; attention end() pointe après le dernier élément du vecteur
// FONCTION ERASE
// (1) Efface un élément
// (2) Efface une série d'éléments
std::cout << "ERASE (1)" << std::endl;
MonVecteur.erase(MonVecteur.begin()); // Efface le premier élément
afficher(MonVecteur);
reinitialiser(MonVecteur);
std::cout << "ERASE (2)" << std::endl;
MonVecteur.erase(MonVecteur.begin(),MonVecteur.end()); // Efface du premier au dernier élément (équivalent d'un clear)
afficher(MonVecteur);
reinitialiser(MonVecteur);
// FONCTION FRONT
// Equivalent BACK pour le début du vecteur
// GET_ALLOCATOR
// Récupère le système d'allocation utilisée par un vecteur pour par exemple fabriquer un nouveau vecteur sur la base de cette allocation
std::cout << "GET_ALLOCATOR" << std::endl;
std::vector<int> vecteurAllocationCommeMonVecteur(MonVecteur.get_allocator() );
std::vector<double> Unvecteuravecuneautreallocation;
if(Unvecteuravecuneautreallocation.get_allocator().max_size()!=MonVecteur.get_allocator().max_size())
std::cout << "espace maximale alloue par int et double est different !" << std::endl;
// INSERT
// Insère de nouveaux éléments dans le vecteur
std::cout << "INSERT (1)" << std::endl;
std::vector<int>::iterator IteEndroitInsere=MonVecteur.end();
IteEndroitInsere--; // On va insérer le nouvel élément à l'avant dernière position
MonVecteur.insert(IteEndroitInsere,42);
afficher(MonVecteur);
std::cout << "INSERT (2)" << std::endl;
IteEndroitInsere=MonVecteur.begin();
MonVecteur.insert(IteEndroitInsere+2,4,1); // On insère 4 fois 1 au niveau de l'itérateur IteEndroitInsere
afficher(MonVecteur);
std::cout << "INSERT (3)" << std::endl;
IteEndroitInsere=MonVecteur.begin();
MonVecteur.insert(IteEndroitInsere+4,MonVecteur2.begin(),--MonVecteur2.end()); // On insère tous les éléments du vecteur 2 sauf le dernier au niveau de l'itérateur IdeEndroitInsere
afficher(MonVecteur);
reinitialiser(MonVecteur);
// MAX_SIZE
// Renvoie la taille maximale que peut prendre le vecteur
std::cout << "MAX_SIZE" << std::endl;
std::cout << "Taille maximale du vecteur : " << MonVecteur.max_size() << std::endl;
// POP_BACK
// Efface le dernier élément du vecteur
afficher(MonVecteur);
MonVecteur.pop_back();
afficher(MonVecteur);
reinitialiser(MonVecteur);
// PUSH_BACK
// Insère un élément à la dernière position du vecteur
afficher(MonVecteur);
MonVecteur.push_back(42);
afficher(MonVecteur);
reinitialiser(MonVecteur);
// RBEGIN
// Permet de parcourir le vecteur inversé
// (1) Renvoie un itérateur modifiable sur le premier élémént du vecteur inversé
// (2) Renvoie un itérateur non modifiable sur le premier élément
std::cout << "RBEGIN (1)" << std::endl;
std::vector<int>::reverse_iterator UnRIterateur; // Déclaration d'un reverse itérateur sur un vecteur d'entiers
UnRIterateur = MonVecteur.rbegin(); // On lui attribue l'adresse du premier élément du vecteur inversé
std::cout << *UnRIterateur << std::endl; // Affichage du contenu du pointeur
*UnRIterateur = 777; // Modification du premier élément
std::cout << *UnRIterateur << std::endl; // Affichage du contenu du pointeur
UnRIterateur++; // On pointe maintenant sur le deuxième élément
std::cout << *UnRIterateur << std::endl; // Affichage du contenu du pointeur
reinitialiser(MonVecteur);
std::cout << "RBEGIN (2)" << std::endl;
std::vector<int>::const_reverse_iterator UnRIterateurConstant; // Déclaration d'un itérateur constant sur un vecteur d'entiers
UnRIterateurConstant = MonVecteur.rbegin();
std::cout << *UnRIterateurConstant << std::endl; // Affichage du contenu du pointeur
// *UnRIterateurConstant = 666; //---> Ca ne compile pas, le contenu du pointeur est protégé
UnRIterateurConstant++; // Ca par contre, je peux. Je me balade donc sur les éléments du vecteur inversé, sans pouvoir les modifier
std::cout << *UnRIterateurConstant << std::endl; // Affichage du contenu du pointeur
reinitialiser(MonVecteur);
// REND
// Permet de parcourir le vecteur inversé en fournissant un pointeur après le dernier élément du vecteur
// (1) Renvoie un itérateur modifiable sur le dernier élémént du vecteur inversé
// (2) Renvoie un itérateur non modifiable sur le dernier élément
std::cout << "REND (1)" << std::endl;
std::vector<int>::reverse_iterator UnRIterateurEnd; // Déclaration d'un reverse itérateur sur un vecteur d'entiers
UnRIterateurEnd = MonVecteur.rend(); // On lui attribue l'adresse du premier élément du vecteur inversé
std::cout << *UnRIterateurEnd << std::endl; // Affichage du contenu du pointeur : rend une valeur "fausse" puisque nous sommes en dehors du vecteur inversé
UnRIterateurEnd--; // Modification du dernier élément (du vecteur inversé)
std::cout << *UnRIterateurEnd << std::endl; // Affichage du contenu du pointeur
UnRIterateurEnd--; // On pointe maintenant sur le deuxième élément
std::cout << *UnRIterateurEnd << std::endl; // Affichage du contenu du pointeur
UnRIterateurEnd--; // On pointe maintenant sur le troisième et dernier élément
std::cout << *UnRIterateurEnd << std::endl; // Affichage du contenu du pointeur
reinitialiser(MonVecteur);
std::cout << "REND (2)" << std::endl;
std::vector<int>::const_reverse_iterator UnRIterateurConstantEnd; // Déclaration d'un itérateur constant sur un vecteur d'entiers
UnRIterateurConstantEnd = MonVecteur.rend();
UnRIterateurConstantEnd--;
std::cout << *UnRIterateurConstantEnd << std::endl; // Affichage du contenu du pointeur
// *UnRIterateurConstant = 666; //---> Ca ne compile pas, le contenu du pointeur est protégé
UnRIterateurConstantEnd--; // Ca par contre, je peux. Je me balade donc sur les éléments du vecteur inversé, sans pouvoir les modifier
std::cout << *UnRIterateurConstantEnd << std::endl; // Affichage du contenu du pointeur
reinitialiser(MonVecteur);
// RESERVE
// Réserve de la place pour le vecteur
std::cout << "RESERVE (1)" << std::endl;
MonVecteur.reserve(20); // Je réserve 20 places pour mon vecteur (voir la fonction capacity)
afficher(MonVecteur);
reinitialiser(MonVecteur);
// RESIZE
// Redéfinit la taille du vecteur
// (1) En indiquant la nouvelle taille
// (2) En indiquant la nouvelle taille et la valeur des éléments à ajouter le cas échéant
std::cout << "RESIZE (1)" << std::endl;
MonVecteur.resize(10); // Nouvelle taille du vecteur : 10
afficher(MonVecteur);
MonVecteur.resize(2);
afficher(MonVecteur);
std::cout << "RESIZE (2)" << std::endl;
MonVecteur.resize(10,67);
afficher(MonVecteur);
MonVecteur.resize(4,68); // Deuxième paramètre superflu, puisque la nouvelle taille impose une réduction du vecteur
afficher(MonVecteur);
reinitialiser(MonVecteur);
// SIZE
// Renvoie la taille du vecteur
std::cout << "SIZE (1)" << std::endl;
std::cout << "La taille de MonVecteur est : " << MonVecteur.size() << std::endl;
// SWAP
// (1) Echange les éléments de deux vecteurs
// (2) Echange les éléments de deux vecteurs (fonction amie)
std::cout << "SWAP (1)" << std::endl;
MonVecteur2.clear();
MonVecteur2.push_back(90); // Remplissage de MonVecteur2
MonVecteur2.push_back(25);
MonVecteur2.push_back(39);
MonVecteur2.push_back(70);
MonVecteur.swap(MonVecteur2);
afficher(MonVecteur);
std::cout << "SWAP (2)" << std::endl;
swap(MonVecteur,MonVecteur2);
afficher(MonVecteur);
// SPECIALISATION DU VECTEUR DANS LE CAS DE BOOLEENS
// Un booléen du vecteur va être stocké sur un bit au lieu d'être stocké sur un octet
// Pour vérifier cela, nous allons comparer la capacité d'un vecteur de booléens
// et celle d'un vecteur de char (un char tenant sur un bit)
std::cout << "Specialisation du vecteur dans le cas de booleens" << std::endl;
std::vector<bool> VecteurLogique;
std::vector<char> VecteurChar;
VecteurLogique.push_back(true);
VecteurChar.push_back('c');
std::cout << "Capacite vecteur logique : " << VecteurLogique.capacity() << std::endl;
std::cout << "Capacite vecteur char : " << VecteurChar.capacity() << std::endl;
// Avec l'affichage ci-dessus, nous remarquons que la capacité du vecteur logique est bien supérieure à celle du char
// Typiquement celle du bool est de 32 et celle du char de 1
VecteurLogique.push_back(true);
VecteurChar.push_back('c');
std::cout << "Capacite vecteur logique : " << VecteurLogique.capacity() << std::endl;
std::cout << "Capacite vecteur char : " << VecteurChar.capacity() << std::endl;
// L'ajout d'un bool ne modifie pas la capacité toujours à 32
for(int ind=0;ind<30;ind++)
{
VecteurLogique.push_back(true);
VecteurChar.push_back('c');
}
// Je complète le vecteur logique pour qu'il ait 32 valeurs (nous en avions déjà 2, je lui en mets 30 supplémentaires)
std::cout << "Capacite vecteur logique : " << VecteurLogique.capacity() << std::endl;
std::cout << "Capacite vecteur char : " << VecteurChar.capacity() << std::endl;
// La capacité du vecteur logique est atteinte...
VecteurLogique.push_back(true);
VecteurChar.push_back('c');
// En rajoutant un élément, je la fais basculer à 64 (le bit "débordant" a provoqué l'allocation d'un nouvel octet de 32 bits où peuvent potentiellement être stockés 32 booléens)
std::cout << "Capacite vecteur logique : " << VecteurLogique.capacity() << std::endl;
std::cout << "Capacite vecteur char : " << VecteurChar.capacity() << std::endl;
// La spécialisation de vector<bool> représente donc un gain de places
// Voir la contre partie en lisant les commentaires de steve_clamage
}
// AFFICHER
// Affiche tous les éléments de MonVecteur
void afficher(const std::vector<int> &VecteurAafficher)
{
std::cout << "***" << std::endl;
if(!VecteurAafficher.empty())
{
std::vector<int>::const_iterator Iterateurvecteur; // Construction d'un itérateur pour parcourir les éléments du vecteur
for(Iterateurvecteur=VecteurAafficher.begin();Iterateurvecteur!=VecteurAafficher.end();Iterateurvecteur++)
{
std::cout << "Valeur de l'iterateur : " << (*Iterateurvecteur) << std::endl; // L'itérateur est un pointeur sur un élément du vecteur. Pour avoir son contenu il faut donc mettre la petite étoile devant.
}
}
else
{
std::cout << "le vecteur est vide" << std::endl;
}
std::cout << "***" << std::endl;
}
// REINITIALISER
// Réinitialise le vecteur avec une série de nombre
void reinitialiser(std::vector<int> &VecteurAinitialiser)
{
VecteurAinitialiser.clear();
VecteurAinitialiser.push_back(38); // On remplit le vecteur avec différents éléments par des "push_back"
VecteurAinitialiser.push_back(26); // Chaque push_back ajoute un élément à le vecteur en le plaçant à la dernière position
VecteurAinitialiser.push_back(73);
}
Conclusion
Voir aussi std::list http://www.cppfrance.com/code.aspx?id=29457 qui traite de std::list
Historique
- 24 février 2005 20:43:01 :
- Prise en compte des remarques d'Hylvenir (voir commentaires) : ajout de l'opérateur [] ; afficher et reinitialiser prennent maintenant un vecteur en paramètre ce qui permet de ne plus déclarer MonVecteur comme variable globale ; quelques lignes de plus sur get_allocator
Suppression d'include qui n'avait rien à faire ici
- 02 mars 2005 08:01:22 :
- Rajout de lignes sur la spécialisation du vector lorsque celui contient des valeurs logiques suivant la remarque de steve_clamage (optimisation de l'occupation mémoire).
Sources du même auteur
Sources de la même categorie
Commentaires et avis
|
Comparez les prix Nouvelle version
|