Considérons un programme dont l’exécution donne :
Saisissez dix valeurs : 1 : 4 2 : 7 3 : 34 4 : 1 5 : 88 6 : 22 7 : 74 8 : 19 9 : 3 10 : 51 Saisissez une valeur : 22 22 est la 6-eme valeur saisie.
Comment programmer cela sans utiliser 10 variables pour stocker les dix premières valeurs saisies ?
Une tableau est un regroupement de variables de même type, il est
identifié par un nom. Chacune des variables du tableau est numérotée,
ce numéro s’appelle un indice. Chaque variable du tableau est
donc caractérisée par le nom du tableau et son indice.
Si par exemple, T est un tableau de 10 variables, alors chacune
d’elles sera numérotée et il sera possible de la retrouver en
utilisant simultanément le nom du tableau et l’indice de la
variable. Les différentes variables de T porteront des numéros de
0 à 9, et nous appellerons chacune de ces variables un
élément de T.
Une variable n’étant pas un tableau est appelée variable
scalaire, un tableau par opposition à une variable scalaire
est une variable non scalaire.
Comme les variables d’un tableau doivent être de même type, il convient de préciser ce type au moment de la délaration du tableau. De même, on précise lors de la déclaration du tableau le nombre de variables qu’il contient. La syntaxe est :
<type>[] <nomdutableau> = new <type>[<taille>]; |
Par exemple,
int[] T = new int[4]; |
déclare un tableau
T
contenant 4 variables de type
int
.
Attention !
<
type
>[] <
nomdutableau
>
n’est pas un
tableau ! C’est une variable contenant un tableau. Cela signifie que
tant que vous ne lui avez pas affecté
new
<
type
>[<
taille
>]
, vous ne pouvez pas l’utiliser.
Il est possible d’initialiser les éléments d’un tableau à la déclaration, on fait cela comme pour des variables scalaires :
<type> <nom> = <valeur d initialisation>; |
La seule chose qui change est la façon d’écrire la valeur d’initialisation, on ecrit entre accolades tous les éléments du tableau, on les dispose par ordre d’indice croissant en les séparant par des virgules. La syntaxe générale de la valeur d’initialisation est donc :
<type>[] <nom> = new <type>[<taille>]{<valeur_0>, <valeur_1>, ..., <valeur_n-1>}; |
Par exemple, on crée un tableau contenant les 5 premiers nombres impairs de la sorte :
int[] T = new int[5]{1, 3, 5, 7, 9}; |
Lorsqu’un tableau est initialisé à la déclaration, il est même possible d’omettre sa taille :
int[] T = new int[]{1, 3, 5, 7, 9}; |
... voire une partie de sa déclaration :
int[] T = {1, 3, 5, 7, 9}; |
Les éléments d’un tableau à n éléments sont indicés de 0 à
n−1. On note
T
[
i
]
l’élément d’indice i du tableau
T
. Les cinq éléments du tableau de l’exemple ci-avant sont
donc
notés
T
[0]
,
T
[1]
,
T
[2]
,
T
[3]
et
T
[4]
.
Nous pouvons maintenant mettre en place le programme du début du
cours. Il est nécessaire de stocker 10 valeurs de type entier, nous
allons donc déclarer un tableau
e
de la sorte :
int[] e = new int[10]; |
La déclaration ci-dessus est celle d’un tableau de 10
int
appelé
e
. Il convient ensuite d’effectuer les saisies des
10 valeurs. On peut par exemple procéder de la sorte :
Console.Write("Saisissez dix valeurs : \n"); Console.Write("1 : "); e[0] = int.Parse(Console.ReadLine()); Console.Write("2 : "); e[1] = int.Parse(Console.ReadLine()); Console.Write("3 : "); e[2] = int.Parse(Console.ReadLine()); Console.Write("4 : "); e[3] = int.Parse(Console.ReadLine()); Console.Write("5 : "); e[4] = int.Parse(Console.ReadLine()); Console.Write("6 : "); e[5] = int.Parse(Console.ReadLine()); Console.Write("7 : "); e[6] = int.Parse(Console.ReadLine()); Console.Write("8 : "); e[7] = int.Parse(Console.ReadLine()); Console.Write("9 : "); e[8] = int.Parse(Console.ReadLine()); Console.Write("10 : "); e[9] = int.Parse(Console.ReadLine()); |
Les divers copier/coller necéssaires pour rédiger un tel code sont d’une laideur à proscrire. Nous procéderons plus élégament en faisant une boucle :
Console.WriteLine("Saisissez dix valeurs :"); for(int i = 0 ; i < 10 ; i++) { Console.Write(i+1 + " : "); e[i] = int.Parse(Console.ReadLine()); } |
Ce type de boucle s’appelle un parcours de tableau. En règle générale on utilise des boucles pour manier les tableaux, celles-ci permettent d’effectuer un traitement sur chaque élément d’un tableau. Ensuite, il faut saisir une valeur à rechercher dans le tableau :
Console.WriteLine("Saisissez une valeur :"); t = int.Parse(Console.ReadLine()); |
Nous allons maintenant rechercher la valeur
t
dans le tableau
e
. Considérons pour ce faire la boucle suivante :
i = 0; while (e[i] != t) i++; |
Cette boucle parcourt le tableau jusqu’à trouver un élément de
e
qui ait la même valeur que
t
. Le problème qui
pourrait se poser est que si
t
ne se trouve pas dans le
tableau
e
, alors la boucle pourrait ne pas s’arrêter. Si
i
prend des valeurs strictement plus grandes que 9, alors
il se produira ce que l’on appelle un débordement
d’indice. Vous devez toujours veiller à ce qu’il ne se produise pas
de débordement d’indice ! Nous allons donc faire en sorte que la
boucle s’arrête si
i
prend des valeurs strictement
supérieures à 9.
i = 0; while (i < 10 && e[i] != t) i++; |
Il existe donc deux façons de sortir de la boucle :
i
< 10
ne
sera pas vérifiée. Une fois sorti de la boucle,
i
aura la
valeur 10.
t
se trouve dans le tableau à l’indice
i
, alors la condition
e
[
i
] !=
t
ne sera pas
vérifiée et on sortira de la boucle. Un fois sorti de la boucle,
i
aura comme valeur l’indice de l’élément de
e
qui est égal à
t
, donc une valeur comprise entre 0 et 9.
On identifie donc la façon dont on est sorti de la boucle en testant la
valeur de
i
:
if (i == 10) Console.WriteLine(t + " ne fait pas partie des dix valeurs saisies."); else Console.WriteLine(t + " est la " + (i + 1) + "-eme valeur saisie."); |
Si
(
i
== 10)
, alors nous sommes sorti de la boucle parce que
l’élément saisi par l’utilisateur ne trouve pas dans le tableau. Dans
le cas contraire,
t
est la
i
+1
-ème valeur saisie par
l’utilisateur. On additionne 1 à l’indice parce que l’utilisateur ne
sait pas que dans le tableau les éléments sont indicés à partir de
0. Récapitulons :
using System; namespace TPTableaux { class MainClass { public static void Main (string[] args) { int[] e = new int[10]; int i; Console.WriteLine("Saisissez 10 valeurs : "); for (i = 0 ; i < 10 ; i++) { Console.Write (i + 1 + " : "); e[i] = int.Parse (Console.ReadLine()); } Console.WriteLine("Saisissez une valeur : "); int t = int.Parse (Console.ReadLine()); i = 0; while(i < 10 && e[i] != t) i++; if (i == 10) Console.WriteLine (t + " ne fait pas partie des dix valeurs saisies."); else Console.WriteLine (t + " est la " + (i + 1)+ "-ème valeur saisie."); } } } |
foreach
Il est possible de parcourir un tableau de façon séquentielle et en
lecture seule grâce à l’instruction
foreach
.
foreach(<type> <variable> in <tableau>) <instructions> |
Cette instruction affecte à
<
variable
>
pour chaque
itération de la boucle un élément de
<
tableau
>
. On
remarque au passage que le
<
type
>
doit être celui des
éléments de
<
tableau
>
. Par exemple, le programme suivant
affiche les quatre premières lettres de l’alphabet :
char[] t = {'a', 'b', 'c', 'd'}; foreach(char c in t) Console.WriteLine(c); |