Collections et boucle «pour tout … dans …»#
Collections : définition et exemples#
Définition : Collection
Une
collection (collection datatype) est une valeur composite homogène
(elle regroupe plusieurs valeurs du même type).
Exemple
Un tableau (vector
) est une collection
Dans un tableau, les valeurs sont dans un ordre donné, en tenant compte des répétitions :
#include<vector>
using namespace std;
vector<int> v = { 3, 2, 5, 2 };
v
Cela donne un sens au i-ième élément d’un tableau :
v[3]
Note
Il existe d’autres types de collections. Voyons quelques exemples.
Ensembles (set
)#
Lorsque l’on souhaite ne tenir compte ni de l’ordre, ni des
répétitions – comme dans un ensemble mathématique – on peut utiliser
un set
:
#include <set>
using namespace std;
set<int> s = { 3, 2, 5, 2};
s
Du coup, accéder au i-ième élément n’a pas de sens :
s[0]
Multi-ensembles (multiset
)#
Si l’on ne souhaite pas tenir compte de l’ordre mais tout de même
des répétitions, on peut utiliser un multi-ensemble (multiset
) :
multiset<int> m = { 3, 2, 5, 2 };
m
m[0]
La boucle for each
#
Une opération omniprésente sur une collection est de parcourir ses valeurs : jusqu’ici on l’a fait à l’aide d’un indice :
#include<vector>
#include<iostream>
using namespace std;
vector<int> v = { 3, 2, 5, 2 };
for ( int i=0; i < v.size(); i++ ) {
cout << v[i] << endl;
}
Cet idiome est un peu lourd et sujet à erreurs. Surtout, il ne se généralise pas à d’autres collections comme les ensembles! (pourquoi?).
À la place nous allons littéralement écrire «pour toute valeur
dans
v
faire …» :
for ( auto valeur: v ) {
cout << valeur << endl;
}
C’est l’équivalent du for valeur in v:
de Python.
Et cela fonctionne tout aussi bien pour toute autre collection :
#include<set>
set<int> s = { 3, 2, 5, 2 };
for ( auto valeur: s ) {
cout << valeur << endl;
}
multiset<int> m = { 3, 2, 5, 2 };
for ( auto valeur: m ) {
cout << valeur << endl;
}
La boucle for each (for each loop) : syntaxe et sémantique#
Syntaxe
for ( auto identificateur: collection ) {
bloc d instructions;
}
Sémantique
Pour chaque élément de la collection tour à tour, affecter la valeur de l’élément à l’identificateur et exécuter le bloc d’instructions.
Attention
Du fait de l’affectation, la boucle for each
parcourt des copies des
valeurs de la collection. En particulier, une affectation
identificateur = ...
ne change pas le tableau d’origine.
Vous verrez au second semestre comment changer cela lorsque souhaitable, en utilisant une référence.
Exemple
Quelle est la valeur de m
après l’instruction suivante?
#include<vector>
using namespace std;
vector<int> m = { 3, 2, 5, 2 };
for ( auto valeur: m ) {
valeur = 1;
}
m
Digression : à propos de auto
♣#
Vous vous demandez peut-être quelle est la
signification de auto
?
On est en train de déclarer une nouvelle variable.
Il faut donc préciser son type. On pourrait très
bien mettre int
comme type puisque l’on manipule
des collections d’entiers :
for ( int valeur: v ) {
cout << valeur << endl;
}
Mais c’est redondant.
Définition : auto
auto (auto (c++ keyword)) est un type spécial qui indique à C++ de sélectionner automatiquement le type adéquat en fonction du contexte. On appelle cela de l”inférence de type.
auto i = 1;
i
auto pi = 3.14;
pi