Aller au menu - Aller au contenu

Icône Les tableaux

Mise à jour : 27/05/2011
Difficulté : Facile Facile Durée d'étude : 1 jour Creative Commons BY-NC-SA
75 639 visites depuis 7 jours, dont 1 912 sur ce chapitre classé 5/786
Vous êtes encore là ?

Bien ! Vous êtes maintenant familiers avec la notion de variable et vous avez pu voir à quel point les utiliser est important. Il est temps maintenant d'aborder des types de variables un petit peu plus complexes : les tableaux.

Dans de très nombreux programmes, on a besoin d'avoir plusieurs variables du même type et qui jouent quasiment le même rôle. Pensez par exemple à la liste des utilisateurs d'un site web. Cela représente une grande quantité de variables de type string. Ou les dix meilleurs scores de votre jeu que l'on stockera dans différentes cases mémoires, toutes de type int.
Le C++, comme presque tous les langages de programmation, propose un moyen simple de regrouper des données identiques en un seul paquet. Et comme l'indique le titre du chapitre, on appelle ces regroupements de variables des tableaux.

Dans ce chapitre, je vais vous apprendre à manipuler deux sortes de tableaux. Ceux dont la taille est connue à l'avance, comme pour la liste des dix meilleurs scores. Et ceux dont la taille peut varier en permanence comme la liste des visiteurs d'un site web qui, généralement, ne cesse de grandir.
Vous vous en doutez certainement, les tableaux dont la taille est fixée à l'avance sont plus faciles à utiliser et c'est donc par eux que nous allons commencer.
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

Les tableaux statiques

Je vous ai parlé dans l'introduction de l'intérêt des tableaux dans le cas où l'on a plusieurs variables du même type à stocker. Voyons cela avec un exemple bien connu, la liste des meilleurs scores du jeu révolutionnaire que vous allez créer un jour. :soleil:

Un exemple d'utilisation



Si vous voulez afficher la liste des 5 meilleurs scores des joueurs, il va vous falloir en réalité deux listes. La liste des noms de joueurs et la liste des scores qu'ils ont obtenus. Il va donc falloir déclarer 10 variables pour mettre toutes ces informations dans la mémoire de l'ordinateur. On aura par exemple :

Code : C++ - Les variables du 'Hall of fame'
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
string nomMeilleurJoueur1("Nanoc");
string nomMeilleurJoueur2("M@teo21");
string nomMeilleurJoueur3("Albert Einstein");
string nomMeilleurJoueur4("Isaac Newton");
string nomMeilleurJoueur5("Archimede");

int meilleurScore1(118218);
int meilleurScore2(100432);
int meilleurScore3(87347);
int meilleurScore4(64523);
int meilleurScore5(31415);


Et pour afficher tout ça, il va aussi falloir pas mal de travail.

Code : C++ - Affichage du 'Hall of fame'
1
2
3
4
5
cout << "1) " << nomMeilleurJoueur1 << " " << meilleurScore1 << endl;
cout << "2) " << nomMeilleurJoueur2 << " " << meilleurScore2 << endl;
cout << "3) " << nomMeilleurJoueur3 << " " << meilleurScore3 << endl;
cout << "4) " << nomMeilleurJoueur4 << " " << meilleurScore4 << endl;
cout << "5) " << nomMeilleurJoueur5 << " " << meilleurScore5 << endl;


Ce qui fait énormément de lignes ! Imaginez maintenant que vous vouliez afficher les 100 meilleurs scores et pas seulement les 5 meilleurs. Ça serait terrible. Il vous faudrait déclarer 200 variables et écrire 100 lignes quasiment identiques pour l'affichage ! Autant arrêter tout de suite, c'est beaucoup trop de travail. :lol:

C'est là qu'interviennent les tableaux. Nous allons pouvoir déclarer les 100 meilleures scores et les noms des 100 meilleurs joueurs d'un seul coup. On va créer une seule case dans la mémoire qui aura de la place pour contenir les 100 int qu'il nous faut et une deuxième pour contenir les 100 string. Magique non ?

Il faut quand même que les variables aient un lien entre elles pour que l'utilisation d'un tableau soit justifiée. Mettre dans un même tableau l'âge de votre chien et le nombre d'internautes connectés n'est pas correct. Même si ces deux variables sont des int.


Dans cet exemple, nous avons besoin de 100 variables. C'est-à-dire 100 places dans le tableau. C'est ce qu'on appelle, en termes techniques, la taille du tableau. Si la taille du tableau reste inchangée et est fixée dans le code source, alors on parle d'un tableau statique. Parfait ! C'est ce dont nous avons besoin pour notre liste des 100 meilleurs scores.

Déclarer un tableau statique



Comme toujours en C++, une variable est composée d'un nom et d'un type. Comme les tableaux sont des variables, cette règle reste valable. Il faut juste ajouter une propriété supplémentaire, la taille du tableau. Autrement dit, le nombre de compartiments que notre case mémoire va pouvoir contenir.

La déclaration d'un tableau est très similaire à celle d'une variable :

Déclaration d'un tableau statique

On indique le type, puis le nom choisi et enfin la taille du tableau entre crochets. Voyons ça avec un exemple.

Code : C++ - Votre premier tableau
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#include <iostream>
using namespace std;

int main()
{
   int meilleurScore[5];   //Declare un tableau de 5 entiers 

   double anglesTriangle[3];   //Declare un tableau de 3 double

   return 0;
}


Voyons à quoi ressemble la mémoire avec un de nos schémas habituels.

La mémoire de l'ordinateur après avoir déclaré deux tableaux


On retrouve nos deux zones mémoires avec leurs étiquettes, mais cette fois, chaque zone est découpée en cases. Trois cases pour le tableau anglesTriangle et cinq cases pour le tableau meilleurScore. Pour l'instant toutes ces cases ne sont pas initialisées. Leur contenu est donc quelconque.

Il est également possible de déclarer un tableau en utilisant comme taille une constante de type int ou unsigned int. On indique simplement le nom de la constante entre les crochets plutôt qu'un nombre.

Code : C++
1
2
int const tailleTableau(20);  //La taille du tableau
double anglesIcosagone[tailleTableau];


Il faut impérativement utiliser une constante comme taille du tableau.


Je vous conseille de toujours utiliser des constantes comme taille de vos tableaux plutôt que d'indiquer directement la taille entre les crochets. C'est une bonne habitude à prendre.

Bon. On a de la place dans la mémoire. Il ne nous reste plus qu'à l'utiliser. :soleil:

Accéder aux éléments d'un tableau



Chaque case d'un tableau peut être utilisée comme n'importe quelle autre variable. Il n'y a aucune différence. Il faut juste y accéder d'une manière un peu spéciale. Il faut indiquer le nom du tableau et le numéro de la case. Dans le tableau meilleurScore, on a accès à cinq variables. La première case de meilleurScore, la deuxième, etc, jusqu'à la cinquième.

Pour accéder à une case on utilise la syntaxe nomDuTableau[numeroDeLaCase]. Il y a juste une petite subtilité, la première case possède le numéro 0 et pas 1. Tout est en quelque sorte décalé de 1. Pour accéder à la 3e case de meilleurScore et y écrire une valeur, il faudra donc écrire :

Code : C++
1
meilleurScore[2] = 5;


En effet, 3-1=2, la 3e case possède le numéro 2. Si je veux remplir mon tableau des meilleurs scores comme dans l'exemple initial, je peux donc écrire :

Code : C++ - Remplissage d'un tableau
1
2
3
4
5
6
7
8
9
int const nombreMeilleursScores(5);  //La taille du tableau

int meilleursScores[nombreMeilleursScores];  //Declaration du tableau

meilleursScores[0] = 118218; //Remplissage de la premiere case
meilleursScores[1] = 100432; //Remplissage de la deuxiemecase
meilleursScores[2] = 87347; //Remplissage de la troisieme case
meilleursScores[3] = 64523; //Remplissage de la quatrieme case
meilleursScores[4] = 31415; //Remplissage de la cinquieme case


Comme tous les numéros de cases sont décalés, la dernière case a le numéro 4 et pas 5 !


Parcourir un tableau



Le gros point fort des tableaux, c'est qu'on peut les parcourir en utilisant une boucle. On peut ainsi effectuer une action sur chacune des cases d'un tableau l'une après l'autre. Par exemple afficher le contenu des cases.

On connaît à priori le nombre de cases du tableau, on peut donc utiliser une boucle for. Nous allons pouvoir utiliser la variable i de la boucle pour accéder au ième élément du tableau. C'est fou, on dirait que c'est fait pour !

Code : C++ - Parcourir un tableau
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
int const nombreMeilleursScores(5);  //La taille du tableau
int meilleursScores[nombreMeilleursScores];  //Declaration du tableau

meilleursScores[0] = 118218; //Remplissage de la premiere case
meilleursScores[1] = 100432; //Remplissage de la deuxiemecase
meilleursScores[2] = 87347; //Remplissage de la troisieme case
meilleursScores[3] = 64523; //Remplissage de la quatrieme case
meilleursScores[4] = 31415; //Remplissage de la cinquieme case

for(int i(0); i<nombreMeilleursScores; ++i)
{ 
    cout << meilleursScores[i] << endl;
}


La variable i va prendre successivement les valeurs 0,1,2,3 et 4. Ce qui veut dire que ce seront les valeurs de meilleursScores[0] puis meilleursScores[1] etc. qui seront envoyées dans cout.

Il faut faire très attention à ne pas dépasser la taille du tableau dans la boucle. Sinon, vous aurez droit à un plantage de votre programme. La dernière case dans cet exemple a le numéro nombreMeilleursScores moins un. Les valeurs autorisées de i sont tous les entiers entre 0 et nombreMeilleursScores moins un compris.


Vous allez voir, le couple tableau - boucle for va devenir votre nouveau meilleur ami. En tout cas je l'espère. ;) C'est un outil très puissant.

Un petit exemple



Allez, je vous propose un petit exemple un petit peu plus complexe. Nous allons utiliser le C++ pour calculer la moyenne de vos notes de l'année. Je vous propose de mettre toutes vos notes dans un tableau et d'utiliser une boucle for pour le calcul de la moyenne.

Vous voyez comment faire ? Parfait ! Je vous regarde. :pirate:

Bon. Ok. J'accepte de vous aider. Voyons donc tout ça étape par étape. Premièrement, il nous faut un tableau pour stocker les notes. Comme ce sont des nombres à virgule, il nous faut des double.

Code : C++
1
2
int const nombreNotes(6);
double notes[nombreNotes];


La deuxième étape consiste à remplir ce tableau avec vos notes. J'espère que vous savez encore comment faire !

Code : C++
1
2
3
4
5
6
7
8
9
int const nombreNotes(6);
double notes[nombreNotes];

notes[0] = 12.5;
notes[1] = 19.5;  //Bieeeen !
notes[2] = 6.;    //Pas bien !
notes[3] = 12;
notes[4] = 14.5;
notes[5] = 15;


Je me répète, mais c'est important. La première case du tableau a le numéro 0. La deuxième a le numéro 1 et ainsi de suite.


Pour calculer la moyenne, il nous faut additionner toutes les notes et ensuite diviser par le nombre de notes. Nous connaissons déjà le nombre de notes, puisque nous avons la constante nombreNotes. Il ne reste donc qu'à déclarer une variable pour contenir la moyenne.

Le calcul de la somme s'effectue dans une boucle for qui va parcourir toutes les cases du tableau.

Code : C++
1
2
3
4
5
6
7
8
double moyenne(0);
for(int i(0); i<nombreNotes; ++i)
{
   moyenne += notes[i];   //On additionne toutes les notes
}
//En arrivant ici, la variable moyenne contient la somme des notes (79.5)
//Il ne reste donc qu'a diviser par le nombre de notes
moyenne /= nombreNotes;


Avec une petite ligne pour l'affichage de la valeur, on obtient le résultat voulu. Un programme qui calcule la moyenne de vos notes.

Code : C++ - Calcul de la moyenne des notes
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
using namespace std;

int main()
{
   int const nombreNotes(6);
   double notes[nombreNotes];

   notes[0] = 12.5;
   notes[1] = 19.5;  //Bieeeen !
   notes[2] = 6.;    //Pas bien !
   notes[3] = 12;
   notes[4] = 14.5;
   notes[5] = 15;
   
   double moyenne(0);
   for(int i(0); i<nombreNotes; ++i)
   {
      moyenne += notes[i];   //On additionne toutes les notes
   }
   //En arrivant ici, la variable moyenne contient la somme des notes (79.5)
   //Il ne reste donc qu'a diviser par le nombre de notes
   moyenne /= nombreNotes;
   
   cout << "Votre moyenne est : " << moyenne << endl;

   return 0;
}



Voyons ce que ça donne quand on l'exécute.

Code : Console
Votre moyenne est : 13.25


Et ça marche ! Vous n'en doutiez pas j'espère. ;)

Les tableaux et les fonctions



Ah ! les fonctions. Vous n'avez pas oublié ce que c'est j'espère. Il faut quand même que je vous en reparle un peu. Comme vous allez le voir, les tableaux et les fonctions ne sont pas les meilleurs amis du monde.

La première restriction est qu'on ne peut pas écrire une fonction qui renvoie un tableau statique. C'est impossible. :(

La deuxième restriction est qu'un tableau statique est toujours passé par référence. Et il n'y a pas besoin d'utiliser l'esperluette (&). C'est fait automatiquement. Cela veut dire que lorsqu'on passe un tableau à une fonction, cette dernière peut le modifier.

Voici donc une fonction qui reçoit un tableau en argument.

Code : C++
1
2
3
4
void fonction(double tableau[])
{
    //...
}


Il ne faut rien mettre entre les crochets.


Mais ce n'est pas tout ! Très souvent, on va vouloir parcourir le tableau, avec une boucle for par exemple. Il nous manque une information cruciale. Vous voyez laquelle ?

La taille ! A l'intérieur de la fonction précédente, il n'y a aucun moyen de connaître la taille du tableau ! Il faut donc impérativement ajouter un deuxième argument contenant la taille. Ce qui donne :

Code : C++
1
2
3
4
void fonction(double tableau[], int tailleTableau)
{
    //...
}


Oui, je sais c'est ennuyeux. Mais il ne faut pas vous en prendre à moi. Je n'ai pas créé le langage. ;)

Pour vous entraîner, je vous propose d'écrire une fonction moyenne() qui calcule la moyenne des valeurs d'un tableau.

Voici ma version :

Secret (cliquez pour afficher)
Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
/*
 *  Fonction qui calcule la moyenne des éléments d'un tableau
 *  - tableau: Le tableau dont on veut la moyenne
 *  - tailleTableau: La taille du tableau
 */
double moyenne(double tableau[], int tailleTableau)
{
   double moyenne(0);
   for(int i(0); i<tailleTableau; ++i)
   {
      moyenne += tableau[i];   //On additionne toutes les valeurs
   }
   moyenne /= tailleTableau;

   return moyenne;
}


Bon bon, assez parlé de ces tableaux. Passons à la suite.

Les tableaux dynamiques

Je vous avais dit que nous allions parler de deux sortes de tableaux différents. Ceux dont la taille est fixée et ceux dont la taille peut varier, les tableaux dynamiques. Certaines choses sont identiques, ce qui va nous permettre de ne pas tout répéter.

Déclarer un tableau dynamique



La première différence se situe au tout début de votre programme. Il faut ajouter la ligne #include <vector> pour utiliser ces tableaux.

A cause de cette ligne, on parle souvent de vector à la place de tableau dynamique. J'utiliserai ce terme parfois dans la suite.


La deuxième grosse différence se situe dans la manière de déclarer un tableau. On utilise la syntaxe

Déclaration d'un vector

Par exemple pour un tableau de 5 entiers, on écrit :

Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include <iostream>
#include <vector> //Ne pas oublier !
using namespace std;

int main()
{
   vector<int> tableau(5);

   return 0;
}


Il faut remarquer trois choses.
  1. Le type n'est pas le premier mot de la ligne comme pour toutes les autres variables.
  2. On utilise une notation bizarre avec un chevron ouvrant et un chevron fermant.
  3. On écrit la taille entre des parenthèses et pas entre crochets.


Ce qui veut dire que ça ne ressemble pas vraiment aux tableaux statiques. o_O Mais vous allez voir, pour parcourir le tableau, le principe est similaire.
Mais avant cela, il y a deux astuces bien pratiques à savoir.

On peut directement remplir toutes les cases du tableau en ajoutant un deuxième argument entre les parenthèses.

Code : C++
1
2
vector<int> tableau(5, 3); //Cree un tableau de 5 entiers valant tous 3
vector<string> listeNoms(12, "Sans nom"); //Cree un tableau de 12 strings valant toutes "Sans nom"


On peut déclarer un tableau sans cases en ne mettant pas de parenthèses du tout.

Code : C++
1
vector<double> tableau; //Cree un tableau de 0 nombres à virgules


Euh... A quoi ça sert un tableau vide ?


Hehe, rappelez-vous que ce sont des tableaux dont la taille peut varier. On peut donc ajouter des cases par la suite. Attendez un peu et vous saurez tout. :)

Accéder aux éléments d'un tableau



La déclaration était très différente des tableaux statiques. Par contre là, c'est exactement identique. On utilise à nouveau les crochets et la première case possède aussi le numéro 0.

On peut donc récrire encore une fois l'exemple de la sous-partie précédente avec un vector.

Code : C++ - Remplissage d'un tableau
1
2
3
4
5
6
7
8
9
int const nombreMeilleursScores(5);  //La taille du tableau

vector<int> meilleursScores(nombreMeilleursScores);  //Déclaration du tableau

meilleursScores[0] = 118218; //Remplissage de la première case
meilleursScores[1] = 100432; //Remplissage de la deuxième case
meilleursScores[2] = 87347; //Remplissage de la troisième case
meilleursScores[3] = 64523; //Remplissage de la quatrième case
meilleursScores[4] = 31415; //Remplissage de la cinquième case


Là, je crois qu'on ne peut pas faire plus facile. :magicien:


Changer la taille



Entrons maintenant dans le vif du sujet. Faire varier la taille d'un tableau. Commençons par ajouter des cases à la fin d'un tableau.

Il faut utiliser push_back(). On écrit le nom du tableau, suivi d'un point et du mot push_back avec entre parenthèses la valeur qui va remplir la nouvelle case.

Code : C++
1
2
vector<int> tableau(3,2); //Un tableau de 3 entiers valant tous 2
tableau.push_back(8);  //On ajoute une 4ème case au tableau. Cette case contient la valeur 8


Voyons ce qui se passe dans la mémoire de plus près.

Effet d'un push_back sur un vector


Une case supplémentaire a été ajoutée au bout du tableau. Tout se fait de manière automatique. C'est fou ce que ça peut être intelligent un ordinateur parfois. ;)

Et bien sûr on peut ajouter beaucoup de cases à la suite les unes des autres.

Code : C++
1
2
3
4
5
6
vector<int> tableau(3,2); //Un tableau de 3 entiers valant tous 2
tableau.push_back(8);  //On ajoute une 4ème case au tableau. Cette case contient la valeur 8
tableau.push_back(7);  //On ajoute une 5ème case qui contient le chiffre 7.
tableau.push_back(14); //Et encore une avec le nombre 14 cette fois.

//Le tableau contient maintenant les nombres : 2 2 2 8 7 14


Et ils ne peuvent que grandir les vectors ?


Non ! Bien sûr que non. Les créateurs du C++ ont pensé à tout. :soleil:

On peut supprimer la dernière case d'un tableau en utilisant la fonction pop_back() de la même manière que push_back(). Sauf qu'il n'y a rien à mettre entre les parenthèses.

Code : C++
1
2
3
vector<int> tableau(3,2); //Un tableau de 3 entiers valant tous 2
tableau.pop_back(); //Et hop ! Plus que 2 cases.
tableau.pop_back(); //Et hop ! Plus qu'une case.


Attention tout de même à ne pas trop supprimer de cases ! Un tableau ne peut pas contenir moins de 0 éléments.


Je crois que je n'ai pas besoin d'en dire plus sur ce sujet.

Il nous reste quand même un petit problème à régler. Comme la taille peut changer, on ne sait pas combien d'éléments un tableau contient de manière certaine. Heureusement, il y a une fonction pour ça. C'est la fonction size(). En faisant tableau.size(), on récupère un entier correspondant au nombre d'éléments de tableau.

Code : C++
1
2
3
4
5
vector<int> tableau(5,4); //Un tableau de 5 entiers valant tous 4
int const taille(tableau.size()); //Une variable pour contenir la taille du tableau
                                  //La taille peut varier mais la valeur de cette variable ne changera pas.
                                  //On utilise donc une constante.
                                  //A partir d'ici, la constante 'taille' vaut donc 5


Retour sur l'exercice



Je crois que le mieux pour se mettre tout ça en tête, est de reprendre l'exercice du calcul des moyennes mais en le refaisant à la "sauce vector".

Je vous laisse essayer. Si vous n'y arrivez pas, voici ma solution :

Code : C++ - Calcul de moyenne en utilisant vector
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <vector> //Ne pas oublier !!
using namespace std;

int main()
{
   vector<double> notes; //Un tableau vide

   notes.push_back(12.5);  //On ajoute des cases avec les notes
   notes.push_back(19.5);
   notes.push_back(6);
   notes.push_back(12);
   notes.push_back(14.5);
   notes.push_back(15);
   
   double moyenne(0);
   for(int i(0); i<notes.size(); ++i)  //On utilise notes.size() pour la limite de notre boucle
   {
      moyenne += notes[i];   //On additionne toutes les notes
   }

   moyenne /= notes.size();  //On utilise a nouveau notes.size() pour obtenir le nombre de notes
   
   cout << "Votre moyenne est : " << moyenne << endl;

   return 0;
}


Wow ! C'est assez différent en fait. :soleil:

On a écrit deux programmes qui font exactement la même chose de deux manières différentes. C'est très courant. Il y a presque toujours plusieurs manières de faire les choses. Chacun choisit celle qu'il préfère.

Les vector et les fonctions



Passer un tableau dynamique en argument à une fonction est beaucoup plus simple que pour les tableaux statiques. Comme pour n'importe quel autre type, il suffit de mettre vector<type> en argument. Et c'est tout. Grâce à la fonction size(), il n'y a même pas besoin d'ajouter un deuxième argument pour la taille du tableau ! :magicien:

Ce qui donne tout simplement :

Code : C++ - Passer un vector en argument d'une fonction
1
2
3
4
void fonction(vector<int> a)   //Une fonction recevant un tableau d'entiers en argument
{
    //...
}


Simple non ? Mais on peut quand même faire mieux. Je vous ai parlé dans le chapitre précédent du passage par référence constante pour optimiser la copie. En effet, si le tableau contient beaucoup d'éléments, le copier prendra du temps. Il vaut donc mieux utiliser cette astuce, ce qui donne :

Code : C++ - Passer un vector en argument d'une fonction
1
2
3
4
void fonction(vector<int> const& a)   //Une fonction recevant un tableau d'entiers en argument
{
    //...
}


Le tableau dynamique ne peut pas être modifié dans ce cas. Pour changer le contenu du tableau, il faut utiliser un passage par référence tout simple (sans le const donc).

Les tableaux multi-dimensionnels

Je vous ai dit en début de chapitre que l'on pouvait créer des tableaux de n'importe quoi. Des tableaux d'entiers, des tableaux de strings, et ainsi de suite. On peut donc créer des tableaux de ... tableaux ! :euh:

Je vous vois d'ici froncer les sourcils et vous demander à quoi cela peut bien servir. Une fois n'est pas coutume, je vous propose de commencer par visualiser la mémoire. Vous verrez peut-être l'intérêt de ce concept pour le moins bizarre.

Un tableau bi-dimensionnel dans la mémoire de l'ordinateur


La grosse case jaune représente, comme à chaque fois, une variable. Cette fois, c'est un tableau de 5 éléments dont j'ai représenté les cases en utilisant des lignes épaisses. A l'intérieur de chacune des cases, on trouve un petit tableau de 4 éléments dont on ne connaît pas la valeur. Pffiou... :-°

Mais si vous regardez attentivement les points d'interrogation, vous pouvez voir une grille régulière ! Un tableau de tableau est donc une grille de variables. Et là, je pense que vous trouvez ça tout de suite moins bizarre.

On parle parfois de tableaux multi-dimensionnels plutôt que de grilles. C'est pour souligner le fait que les variables sont arrangées selon des axes X et Y et pas juste selon un seul axe.


Déclaration d'un tableau multi-dimensionnel



Pour déclarer un tel tableau, il faut indiquer les dimensions les unes après les autres entre crochets.

Code : C++
1
type nomTableau[tailleX][tailleY]


Donc pour reproduire le tableau du schéma, on doit déclarer le tableau suivant.

Code : C++ - Déclaration du tableau du schéma
1
int tableau[5][4];


Ou encore mieux, en déclarant des constantes.

Code : C++ - Déclaration du tableau du schéma
1
2
3
int const tailleX(5);
int const tailleY(4);
int tableau[tailleX][tailleY];


Et c'est tout ! C'est bien le C++ non ?

Accéder aux éléments



Je suis sûr que je n'ai pas besoin de vous expliquer la suite. Vous avez sûrement deviné tout seul. Pour accéder à une case de notre grille, il faut indiquer la position en X et en Y de la case voulue.

Par exemple tableau[0][0] accède à la case en-bas à gauche de la grille. tableau[0][1] correspond à celle qui se trouve juste en-dessus, alors que tableau[1][0] se situe directement à sa droite.

Comment accéder à la case située en-haut à droite ? :pirate:


Hehe. La question piège. C'est la dernière case dans la direction horizontale. Donc entre les premiers crochets, il faut mettre tailleX-1, c'est-à-dire 4. C'est également la dernière case selon l'axe vertical et donc il faut spécifier tailleY-1 entre les seconds crochets. Ce qui donne tableau[4][3].

Aller plus loin



On peut bien sûr aller encore plus loin et créer des grilles tri-dimensionnelles voire même plus. On peut tout à fait déclarer une variable comme ceci :

Code : C++
1
double grilleExtreme[5][4][6][2][7];


Mais là, il ne faudra pas me demander un dessin. ;) Je vous rassure quand même, il est rare de devoir utiliser des grilles à plus de 2 dimensions. Ou alors, c'est que vous prévoyez de faire des programmes vraiment compliqués. :soleil:

Les strings comme tableaux

Avant de terminer ce chapitre, il faut quand même que je vous fasse une petite révélation. Les chaînes de caractères sont en fait des tableaux ! o_O

On ne le voit pas lors de la déclaration, c'est bien caché. Mais il s'agit en fait d'un tableau de lettres. Il y a même beaucoup de points communs avec les vector.

Accéder aux lettres



L'intérêt de voir une chaîne de caractères comme un tableau de lettres, c'est qu'on peut accéder à ces lettres et les modifier. Et je ne vais pas vous surprendre, on utilise aussi les crochets. :)

Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <iostream>
#include <string>
using namespace std;

int main()
{
   string nomUtilisateur("Julien");
   cout << "Vous etes " << nomUtilisateur << "." <<endl;

   nomUtilisateur[0] = 'L';  //On modifie la premiere lettre
   nomUtilisateur[2] = 'c';  //On modifie la troisieme lettre

   cout << "Ah non, vous etes " << nomUtilisateur << "!" << endl;

   return 0;
}


Testons pour voir.

Code : Console
Vous etes Julien.
Ah non, vous etes Lucien!


C'est fort ! Mais on peut faire encore mieux.

Les fonctions



On peut également utiliser size() pour connaître le nombre de lettres et push_back() pour ajouter des lettres à la fin. A nouveau, c'est comme pour vector.

Code : C++
1
2
string texte("Portez ce whisky au vieux juge blond qui fume.");  //46 caractères
cout << "Cette phrase contient "<< texte.size() << " lettres." << endl;


Mais contrairement aux tableaux, on peut ajouter plusieurs lettres d'un coup. Et on utilise le +=.

Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <string>
using namespace std;

int main()
{
   string prenom("Albert"); 
   string nom("Einstein");
   
   string total;    //Une chaine vide
   total += prenom; //On ajoute le prenom a la chaine vide
   total += " ";    //Puis un espace
   total += nom;    //Et finalement le nom de famille

   cout << "Vous vous appelez " << total << "." << endl; 

   return 0;
}


Ce qui donne bien sûr :

Code : Console
Vous vous appelez Albert Einstein.


C'est fou ce que c'est bien le C++ parfois. ;)

Q.C.M.

Quel est l'indice du premier élément d'un tableau ?
Comment déclare-t-on un tableau statique de 10 nombres à virgule ?


Comment sont passés les tableaux statiques aux fonctions ?
Comment afficher la valeur du dernier élément du tableau suivant ?


Code : C++
1
vector<unsigned int> tableau(10,5);

Qu'affiche le code suivant ?


Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <vector>
using namespace std;

int main()
{
   vector<int> tableau(4,2);
   
   tableau.pop_back();
   tableau.push_back(5);
   tableau.push_back(-3);

   for(int i(0); i<tableau.size(); ++i)
   {
       cout << tableau[i] << " ";
   }

   return 0;
}
Qu'affiche ce code ?


Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <iostream>
#include <string>
using namespace std;

int main()
{
   string phrase("blabla");

   phrase += "bla";

   phrase[2] = 'u';

   cout << phrase.size() << endl;

   return 0;
}

Statistiques de réponses au QCM

Nous voici donc au terme de ce chapitre. J'espère que vous aimez déjà les tableaux. Vous verrez, ils vont vite devenir des éléments essentiels de vos programmes.

Dans le chapitre suivant, nous allons voir comment lire et écrire des fichiers. Vous serez ensuite livrés à vous-mêmes pour le premier TP de ce cours. :pirate:
Chapitre précédent Sommaire Chapitre suivant

Partager

54 commentaires pour "Les tableaux"
Note moyenne : 3.85 / 4 (1749 votes)
Pseudo Commentaire
En ligne Nanoc # Posté le 19/03/2012 à 00:41:07
Aimez-vous le C++ ?
Avatar
Validateurs

Ville : Durham
Pays : Royaume-Uni
Études : EPFL

@Maramu: Mais qu'est-ce qui justifie l'utilisation d'un int* à la place d'un vector<int> ?
 
Hors ligne sultana # Posté le 31/03/2012 à 11:55:16

Avis : Très bon

Une question: et comment déclarer un tableau dynamique multi-dimensionnel ?
Hors ligne maramu # Posté le 09/04/2012 à 20:27:57

Avis : Bon

Nanoc: en pratique rien du tout, à part si nous avons besoin de performances très élevées dans le cadre d'algorithme mathématiques complexe par exemple. Mais cela me gênait de présenter les tableaux dynamiques comme étant les vector.
Hors ligne Powa84 # Posté le 20/04/2012 à 05:51:44
Avatar

Études : IUT Montpellier

Citation : Arnaud921
Secret (cliquez pour afficher)
Salut a tous amis zero :)
Encore une fois jaurais besoin d'aide car lorsque j'essaye d'appliquer ce programme :
Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <string>

using namespace std;

double calculMoyenne(double tableau[], int tailleTableau)
{
    double moyenne(0);
    
    cout <<"Entrez vos notes :"<<endl;

    for(int i(1); i<=tailleTableau; i++)
    {
        cout <<i<<"eme note :";
        cin >>tableau[i-1];

        while(tableau[i-1] < 0)
        {
            cout <<"Je ne pense pas que tu aies eu une note négative ! Recommence :";
            cin>>tableau[i-1];
        }
        moyenne +=tableau[i-1];
    }

    moyenne /= tailleTableau;

    cout <<"Votre moyenne sur ces notes est de : "<<moyenne<<endl;

    if(moyenne>=15)
    {
        cout <<"Bien joue ! Vous etes un tres bon eleve !"<<endl;
    }
    else if(moyenne >=13)
    {
        cout <<"Tu es un bon eleve"<<endl;
    }
    else if (moyenne >=10)
    {
        cout <<"Tu es un eleve dans la moyenne"<<endl;
    }
    else
    {
        cout <<"Tu eprouves quelques difficultés, ne lache rien !"<<endl;
    }

    return moyenne;
}
int main()
{
    int nombreNotes;
    double notes[nombreNotes];

    cout <<" Combien avez-vous eu de notes sur l'année? "<<endl;
    cin >>nombreNotes;

    cout<<calculMoyenne(notes, nombreNotes);
    return 0;
}


Il y a une erreur windows avec la fenetre de debogage de programme :/ Il n'y a pas de probleme de compil' mais ca s'execute pas et je vois pas ou est l'erreur ou l'endroit que CodeBolocks comprend pas. j'ai meme essayer de maniere différente :

Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <string>

using namespace std;

double calculMoyenne(double tableau[], int tailleTableau)
{
    double moyenne(0);
    int i(1), j(0);
    do
    {

        cout <<"Quelle votre "<<i<<" e note ?";
        cin>>tableau[j];
        moyenne += tableau[j];
        i+=1;
        j+=1;
    }while(i<=tailleTableau && j<tailleTableau);

    moyenne /= tailleTableau;

    cout <<"Votre moyenne sur ces notes est de : "<<moyenne<<endl;

    if(moyenne>=15)
    {
        cout <<"Bien joue ! Vous etes un tres bon eleve !"<<endl;
    }
    else if(moyenne >=13)
    {
        cout <<"Tu es un bon eleve"<<endl;
    }
    else if (moyenne >=10)
    {
        cout <<"Tu es un eleve dans la moyenne"<<endl;
    }
    else
    {
        cout <<"Tu eprouves quelques difficultés, ne lache rien !"<<endl;
    }

    return moyenne;
}
int main()
{
    int nombreNotes;
    double notes[nombreNotes];

    cout <<" Combien avez-vous eu de notes sur l'année? "<<endl;
    cin >>nombreNotes;

    cout<<calculMoyenne(notes, nombreNotes);
    return 0;
}


Mais ca bug toujours :(
Si vous pourriez m'aider svp :D

Salut

Ligne 51 du 1er code: tu ne peux pas déclarer un tableau dynamique de cette façon.
Et évite les accents ça ne marche pas en console.
Hors ligne Boon63 # Posté le 05/05/2012 à 05:36:41
Avatar

Tout d'abord, chapeau pour les tutos ! Ils sont très bien construits et se lisent tous seuls ! C'est important pour les débutants :)
De mémoire, cette qualité était déjà là, il y a 7 ans ! ('tin, je suis vieux et encore zéro ! \o/)

Sinon, j'ai une question concernant les vector en argument de fonction :

Dans ce cas :
Code : C++
1
2
3
4
void fonction(vector<int> const& a)   //Une fonction recevant un tableau d'entiers en argument
{
    //...
}

le vector n'est pas copié mais n'est pas modifiable.

Quelle est donc la syntaxe pour envoyer un tableau modifiable sans le copier svp ?
(ou comment ecrit-on une référence sur un vector ?)
Ceci n'est pas stipulé dans le tuto.

Est-ce
void fonction(vector<int>& a)
ou
void fonction(vector<int&> a)
ou autre chose ?

D'avance merci ! :)

Voir tous les commentaires