Collections et boucle «pour tout … dans …»#

Collections : définition et exemples#

Definition 64 (Collection)

Une collection est une valeur composite homogène
(elle regroupe plusieurs valeurs du même type).

Example 55

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]

Boucle for each#

Une opération omniprésente sur une collection est de parcourir toutes ses valeurs : jusqu’ici on l’a fait à l’aide d’un index :

#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;
}

C’est un peu lourd, et sujet à erreurs. Surtout, cela ne se généralisera pas aux 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 fonctionnera 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;
}

Example 56

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

Attention

Pour être complètement précis, valeur ne parcourt pas les valeurs de la collection, mais des copies de celles-ci. Aussi, une affectation valeur=... ne change pas le tableau d’origine.

Vous verrez au second semestre comment changer cela lorsque souhaitable, en utilisant une référence.

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.

Definition 65 (auto)

auto 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