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