Page principale | Pages associées

Les Vecteurs

La première partie de ce tutorial avait pour but de faire entrevoir la puissance de la STL. Cette deuxième partie essayera de présenter la STL de manière un peu plus précise tout en restant assez simple pour être accessible à tous.

La STL (Standard Template Library) repose sur la programmation générique à partir des templates. Les templates étant un domaine un peu trop avancé (même pour les compilateurs), je n'en parlerai qu'un minimum. Donc pour faire simple un template permet de définir des familles de fonctions ou d'objets. La syntaxe, déjà vu dans les tutoriaux précédents, est l'utilisation de '<' et '>'. ex: vector< int > vInt; permet de définir un vector sur des entiers (int) appelé vInt. Il suffit de changer int par un autre type pour changer la nature des éléments contenus dans le vector. Pour ce tutorial, nous n'aurons pas besoin d'en savoir plus.

La STL propose en ensemble de conteneurs, d'algorithmes et d'itérateurs. Les conteneurs permettent de manipuler une collection d'éléments d'un certain type, les algorithmes fournissent des traitements pour manipuler des éléments dans les conteneurs, et enfin, les itérateurs permettent aux algorithmes de manipuler les conteneurs sans connaître la nature exact du conteneur sur lequel ils travaillent.

Les conteneurs permettent de stocker des éléments d'un certain type. Deux catégories sont présentes dans la STL : les séquences ( vector, list, deque , ... ), les conteneurs associatifs( set, map, ... ). Il y en a quelques autres dont je ne parlerais pas mais qu'un tutorial complet se doit de présenter.

Les itérateurs sont une généralisation de la notion de pointeur. Un itérateur sur un conteneur permet d'accéder à un élément sur lequel il pointe. Ils permettent de parcourir le conteneur duquel ils sont issus (par l'opérateur ++ par exemple)

Les algorithmes permettent de manipuler les conteneurs grâce aux itérateurs.

Bon, c'est parti...place au code.

Le vector est sûrement le plus simple à utiliser car se rapprochant le plus des tableaux classiques du C grâce à leur accès direct. La particularité des conteneurs de la STL est qu'ils fournissent des types permettant de la manipuler. vector<T>::size_type permet de typer les index du vecteur vector<T>::iterator et vector<T>::const_iterator fournissent les itérateurs pour accéder aux élements et parcourir le vecteur. Pour le moment, ce sont les seuls qui nous intéressent

#include <iostream> #include <vector>
le fichier a inclure pour utiliser les vecteurs

using namespace std;
Permet d'utiliser le namespace dans le source

int main() { // Un vecteur vide vector< int > vInt;
définit un vecteur sur des entiers vide. Il n'y a donc aucun élément dans ce vecteur

// Insertion de 5 éléments de 1 à 5 for ( int i = 1; i < 6; ++i ) { // Insertion de l'élément à la fin du vecteur vInt.push_back( i );
Une autre méthode pour insérer un élément à la fin : vInt.insert( vInt.end(), i ); end() permet d'avoir un itérateur correspondant à la fin du vecteur APRES le dernier élément.

} // Insertion de 5 éléments de 6 à 10 for ( int j = 6; j < 11; ++j ) { // Insertion de l'élément au début du vecteur vInt.insert( vInt.begin(), j );
begin() permet d'avoir un itérateur correspondant au début du vecteur qui POINTE SUR le premier élément. La méthode insert( position, valeur ) permet d'insérer un élément avant la position l.
} // Normalement à ce stade notre vecteur doit contenir 10 éléments. cout << "Taille : " << vInt.size() << endl;
size() permet de connaître le nombre d'éléments dans le vecteur.

// Afficher le premier élément cout << "premier : " << vInt.front() << endl;
front() permet d'avoir accès au premier élément

// Afficher le dernier élément cout << "dernier : " << vInt.back() << endl;
back() permet d'avoir accès au dernier élément

// Afficher le 3ième élément cout << "3ième : " << vInt[2] << endl;
Comme les tableaux en C, l'indexation sur les vecteurs commence à 0. Un autre méthode permettant d'accéder à un élément est at(). La différence vient d'un contrôl des bornes pour at (donc un peu moins performante)

// Suppression du dernier élément vInt.pop_back(); // Affichage du vecteur for ( vector< int >::const_iterator k = vInt.begin(); k != vInt.end(); ++k ) { cout << "Element : " << *k << endl;
Affiche 10, 9, 8, 7, 6, 1, 2, 3, 4 Cette boucle utilise const_iterator et ++i Le const_iterator définit un itérateur dont les éléments sur lequel il pointe sont constants et ne pourront donc pas être modifiés (un iterator simple aurait suffit évidement) ++i permet de faire avance l'itérateur sur l'élément suivant. Il est courant (et pas faux) d'utiliser l'indexation classique pour parcourir un vecteur for ( vector<int>::size_type i = 0; i < vInt.size(); ++i ) cout << "Element : " << vInt[i] << endl; A noter juste l'utilisation de size_type au lieu du classique int dans ce cas
} // Suppression de tous les éléments vInt.clear();

Supprime tous les éléments du vecteur. Il n'est pas nécessaire de vider un vecteur, il se vide proprement tout seul à la sortie de portée.

}

Résumons, cette présentation du vecteur nous permet maintenant:

Le bref itérateur nous a permis de voir qu'on pouvait se déplacer dans le vecteur gràce à ++. On commence à apercevoir l'intéret que pourrait avoir de tels itérateurs pour les algorithmes..

La suite...


Le source complet :
#include <iostream> #include <vector> using namespace std; int main() { // Un vecteur vide vector< int > vInt; // Insertion de 5 éléments de 1 à 5 for ( int i = 1; i < 6; ++i ) { // Insertion de l'élément à la fin du vecteur vInt.push_back( i ); } // Insertion de 5 éléments de 6 à 10 for ( int j = 6; j < 11; ++j ) { // Insertion de l'élément au début du vecteur vInt.insert( vInt.begin(), j ); } // Normalement à ce stade notre vecteur doit contenir 10 éléments. cout << "Taille : " << vInt.size() << endl; // Afficher le premier élément cout << "premier : " << vInt.front() << endl; // Afficher le dernier élément cout << "dernier : " << vInt.back() << endl; // Afficher le 3ième élément cout << "3ième : " << vInt[2] << endl; // Suppression du dernier élément vInt.pop_back(); // Affichage du vecteur for ( vector< int >::const_iterator k = vInt.begin(); k != vInt.end(); ++k ) { cout << "Element : " << *k << endl; } // Suppression de tous les éléments vInt.clear(); }
00001 #include <iostream> 00002 #include <vector> 00003 using namespace std; 00004 int main() 00005 { 00006 // Un vecteur vide 00007 vector< int > vInt; 00008 // Insertion de 5 éléments de 1 à 5 00009 for ( int i = 1; i < 6; ++i ) 00010 { // Insertion de l'élément à la fin du vecteur 00011 vInt.push_back( i ); 00012 } 00013 00014 // Insertion de 5 éléments de 6 à 10 00015 for ( int j = 6; j < 11; ++j ) 00016 { // Insertion de l'élément au début du vecteur 00017 vInt.insert( vInt.begin(), j ); 00018 } 00019 00020 // Normalement à ce stade notre vecteur doit contenir 10 éléments. 00021 cout << "Taille : " << vInt.size() << endl; 00022 // Afficher le premier élément 00023 cout << "premier : " << vInt.front() << endl; 00024 // Afficher le dernier élément 00025 cout << "dernier : " << vInt.back() << endl; 00026 // Afficher le 3ième élément 00027 cout << "3ième : " << vInt[2] << endl; 00028 // Suppression du dernier élément 00029 vInt.pop_back(); 00030 00031 // Affichage du vecteur 00032 for ( vector< int >::const_iterator k = vInt.begin(); 00033 k != vInt.end(); ++k ) 00034 { 00035 cout << "Element : " << *k << endl; 00036 } 00037 00038 // Suppression de tous les éléments 00039 vInt.clear(); 00040 }

Dernière modification : Sun Jul 4 20:19:14 2004