close

Se connecter

Se connecter avec OpenID

Chapitre 7 - Brouchoud.ch

IntégréTéléchargement
7.1
Chapitre 7
LES TABLEAUX
7.1
PRELIMINAIRES
De nombreuses applications font appel à la manipulation de données multiples ayant des caractéristiques
communes correspondant par exemple, en algèbre, à des variables indicées :
. Dans de telles
situations, il est utile de ranger ces informations dans un tableau dont elles partagent le nom, par exemple x.
Les données élémentaires peuvent être indifféremment de type caractère, entier, ou en virgule flottante (réelle),
etc … Ces données élémentaires doivent cependant être toutes du même type.
Chaque élément d’un tableau (i.e. chaque donnée individuelle) est identifié par la mention du nom du tableau,
suivi d’un ou plusieurs indices, compris chacun dans une paire de crochets. Chaque indice doit être une valeur
entière positive ou nulle. Ainsi, les éléments du tableau x de n éléments sont référencés par x[0], x[1], x[2], …,
x[ n - 1].
Le nombre d’indices détermine la dimension du tableau. Par exemple, x[i] fait référence à un élément du
tableau unidimensionnel x. De même, y[i][j] fait référence à un élément du tableau à deux dimensions y. Il est
également possible de construire des tableaux de dimensions supérieures, en ajoutant des indices
supplémentaires, par exemple z[i][j][k].
7.2
DEFINITION D’UN TABLEAU
Un tableau est une variable qui se compose d’un certain nombre de données élémentaires du même type,
rangées en mémoire les unes à la suite des autres. Chaque donnée élémentaire représente en soi une variable.
Le tableau est unidimensionnel lorsque ses éléments ne sont pas eux-mêmes des tableaux. Mais un élément
d’un tableau peut être en soi un tableau, donc un objet de type plus complexe. On obtient alors des tableaux
imbriqués, multidimensionnels. Le terme ‘’tableau’’ admet comme synonymes les mots ‘’vecteur’’ (tableau
unidimensionnel), ‘’table’’ ou ‘’matrice’’.
7.3
TABLEAU UNIDIMENSIONNEL
Un tableau unidimensionnel est composé d’éléments qui ne sont pas eux-mêmes des tableaux, avec un nombre
arbitraire de colonnes mais une seule ligne. Représentation d’un vecteur x d’éléments du type int :
Elément 1
Elément n
Elément 2
Elément n - 1
Elément 3
int
int
x[0]
x[1]
int
x[2]
Elément n - 2
…
int
x[n-3]
int
int
x[n-2]
x[n-1]
La définition d’un tableau unidimensionnel admet la syntaxe suivante :
<Type>
<Nom du tableau>[Nombre d’éléments]
Commentaires
• <Type> spécifie le type d’éléments dont se compose le tableau et peut être de nature char,
int, long, float, double, … ou plus complexe.
• Le nom du tableau obéit aux mêmes règles que pour le nom des variables.
• Le nombre d’éléments est une valeur constante entière. Les crochets autour de cette valeur ne
signifie pas ici que l’indication est optionnelle, mais ils font partie de la syntaxe de la définition.
Exemples
int N[100] ;
char message[25] ;
float x[12] ;
/* N est un tableau de 100 éléments du type entier */
/* message est un tableau de 25 éléments du type caractère */
/* x est un tableau de 12 éléments du type réels flottants */
Lionel Barlatey, 2001 , 2015
7.2
Le fait que le nombre d’éléments est spécifié à la définition entraîne comme conséquence que ce nombre ne
pourra plus être modifié dans la suite du programme. Le nombre d’éléments du tableau est ici une donnée
statique dont la taille n’est pas variable. Il existe cependant des techniques d’allocation dynamique de la
mémoire qui permettent de faire varier la taille d’un tableau en fonction des besoins.
Il est parfois pratique de définir la taille d’un tableau en utilisant une constante symbolique au lieu d’une valeur
entière fixe. Ceci facilite d’éventuelles modifications à porter à un programme, puisque les tailles maximales
de tableaux peuvent être modifiées en changeant simplement la valeur des constantes symboliques.
Application. Conversion en majuscule d’un texte.
/* Ce programme lit un tableau unidimensionnel de caractères, convertit
ses éléments en majuscules, puis affiche le tableau modifié */
#include <stdio.h>
#include <ctype.h>
/* Librairie de la fonction toupper */
#define DIM 80
void main(void)
{
char lettre[DIM] ;
int compteur ;
/* Lecture d’une ligne */
for(compteur = 0 ; compteur < DIM ; compteur = compteur + 1)
lettre[compteur] = getchar() ;
/*Affichage de la ligne convertie */
for(compteur = 0 ; compteur < DIM ; compteur++)
putchar(toupper(lettre[compteur])) ;
}
Commentaire
• La constante symbolique DIM porte ici la valeur 80. Son nom (par opposition à sa valeur) apparaît
dans la définition du tableau ainsi que dans les deux boucles for. De ce fait, pour adapter le
programme à une nouvelle taille de tableau, il suffit de modifier la seule instruction #define.
Indexation d’un tableau unidimensionnel
L’accès à une variable s’effectue par son nom. Un tableau est composé de plusieurs variables individuelles du
même type qu’il faut distinguer nommément si on veut pouvoir y accéder individuellement pour quelque
manipulation que ce soit. Chaque élément du tableau est identifié par un nombre spécifique appelé indice ou
index. Combiné avec le nom de la variable tableau, cet indice donne une description non ambiguë de chaque
élément du tableau.
En langage C, l’indexation commence toujours à 0 (par opposition à 1), ce qui signifie que le premier
élément d’un tableau a l’indice 0, le second l’indice 1, etc …
Exemple
• Le tableau de nom ‘’i’’, défini par int i[4] ; contient les quatre éléments i[0], i[1], i[2]et
i[3]. Chacun des éléments est une variable de type int. Le n-ième élément possède l’indice (n – 1).
Initialisation d’un tableau unidimensionnel
Une des deux méthodes pour initialiser un tableau consiste, après définition du tableau, à munir ses éléments
des valeurs initiales souhaitées au moyen d’affectations appropriées. Une technique élémentaire utilise
l’affectation multiple v[0] = v[1] = v[2] = v[3] = v[4] = 0 pour le tableau comportant 5
éléments entiers int v[5]. Cette méthode devient laborieuse si le nombre d’éléments du tableau est élevé. Il
est plus avantageux, à l’aide d’une boucle et d’une variable de contrôle entière adéquate, de faire prendre à
l’index toutes les valeurs souhaitées afin d’accéder aisément à tous les éléments du tableau pour les initialiser.
int k, v[5] ;
for(k = 0 ; k<5 ;k++)
v[k] = 0 ;
Lionel Barlatey, 2001 , 2015
7.3
La structure répétitive utilisée pour l’initialisation d’un tableau avec la boucle for s’applique également à
l’affichage des éléments du tableau ainsi qu’à la saisie des valeurs que l’utilisateur désire ranger dans le
tableau.
Une autre méthode d’initialisation consiste à affecter des valeurs initiales aux éléments du tableau dès sa
définition. Les valeurs initiales sont séparées par des virgules et placées dans l’ordre, entre accolades, suivant
la syntaxe :
<Type>
<Nom du tableau>[Nombre d’éléments]=
;
Les valeurs
à
doivent être des constantes. Les valeurs initiales sont affectées aux éléments du tableau
dans l’ordre, depuis la gauche vers la droite. Le nombre de valeurs initiales doit correspondre au nombre
d’éléments du tableau. Cependant, si le nombre de valeurs initiales est inférieur au nombre d’éléments du
tableau, les éléments non explicitement initialisés prennent automatiquement la valeur 0. Ceci vaut également
pour les éléments restants d’un tableau dont certains éléments seulement sont initialisés avec une valeur non
nulle.
L’indication du Nombre d’éléments du tableau est facultative lorsque les éléments du tableau sont
initialisés. La taille du tableau est automatiquement ajustée au nombre des valeurs initiales mentionnées dans la
définition.
Exemples
•
int u[10] = {4, 1, 3, 0, 3} ;
4
•
3
0
3
0
0
0
0
0
int v[] = {0, 0, 0, 0, 0} ;
0
•
1
0
0
0
0
float x[6] = {-0.3, 0., 0.25} ;
-0.3
0.
0.25
0.
0.
0.
Remarque
Les chaînes ou tableaux de caractères sont traités de façon différente. Lorsqu’une constante de type
chaîne est affectée à un tableau, la taille de celui-ci est généralement omise, car automatiquement
ajustée, en tenant compte du caractère nul (\0) ajouté automatiquement à la fin de chaque chaîne de
caractères. Considérons les définitions de tableaux suivantes : toutes deux entraînent l’affectation de la
valeur initiale ‘’BLEU’’ mais le premier tableau a 4 éléments tandis que le second est de taille
indéfinie.
char couleur[4] = ’’BLEU’’ ;
char couleur [] = ’’BLEU’’ ;
couleur[0]
couleur[1]
couleur[2]
couleur[3]
=
=
=
=
‘B’
‘L’
‘E’
‘U’
;
;
;
;
couleur[0]
couleur[1]
couleur[2]
couleur[3]
couleur[4]
=
=
=
=
=
‘B’ ;
‘L’ ;
‘E’ ;
‘U’ ;
‘\0’ ;
La première forme est donc incorrecte, puisque le caractère nul ne figure pas dans le tableau. Cette
définition de tableau aurait pu s’écrire char couleur[5] ;.
Manipulation de tableaux et de leurs éléments
Il n’existe pas en C d’opérations simples portant sur l’ensemble des tableaux. Ainsi, si a et b par exemple,
sont des tableaux comparables (de type et de dimensions rigoureusement identiques), les opérations
d’affectation, de comparaison, …, doivent se faire élément par élément. Ceci se fait généralement dans des
boucles, au cours desquelles chaque itération représente le traitement d’un seul élément d’un tableau
particulier. Le nombre de passages dans la (les) boucle(s) est alors déterminé par le nombre d’éléments à
traiter.
Lionel Barlatey, 2001 , 2015
7.4
Exemple
Soit
int i[4] ;
L’instruction
i[2] = 7 ;
L’instruction suivante i[0] = i[2] – 4
affecte la valeur 7 au troisième élément du tableau i.
affecte alors au premier élément du tableau la valeur 3.
Source d’erreurs
Les compilateurs C ne vérifient pas si l’indice est valide, c’est à dire compris entre les bornes 0 et <Indice
maximal>. Si on emploie des indices qui dépassent le maximum autorisé dans la définition du tableau, alors on
adresse des emplacements de mémoire situés hors du tableau, sans
que le compilateur signale
systématiquement cette erreur. De semblables erreurs se produisent lorsque des indices négatifs apparaissent
par inadvertance.
Application
Le programme suivant lit , à l’aide d’une boucle, les valeurs statistiques du nombre de véhicules observés en
un point pour chaque jour de la semaine, puis les range dans un tableau. Les valeurs sont saisies au clavier,
cumulées et réaffichées pour contrôle, ainsi que leur somme.
#include <stdio.h>
void main(void)
{
long vehicles[8] ;
/* Nombre de véhicules pour chacun des 7
jours de la semaine. Pour les jours 1 à 7, on utilise
les éléments vehicles[1] à vehicles[7] du tableau.
L’élément vehicles[0] n’est pas utilisé. */
long s = 0 ;
/* Somme des véhicules comptés*/
int i ;
/* Variable de boucle */
printf(’’Entrer le nombre de vehicules pour chacun des jours’’) ;
printf(’’de 1 à 7:\n’’) ;
for (i = 1 ; i < 8 ; i++)
{
printf(’’Jour %d:’’, i) ;
scanf(’’%ld’’, &vehicles[i]) ;
s = s + vehicles[i] ;
}
printf(’’\n\nVerification des valeurs saisies:\n\n’’) ;
for (i = 1 ; i < 8 ; i++)
printf(’’Jour %d\t’’, i) ;
printf(\n’’) ;
for (i = 1 ; i < 8 ; i++)
/* Boucle d’affichage */
printf(’’%ld\t’’, vehicles[i]) ;
printf(\n\nNombre total de vehicules observes: %ld\n’’, s) ;
}
Commentaires
• Le tableau a été crée avec 8 éléments et non 7 (ce qui conviendrait aussi) afin que le numéro du
jour et l’indice de l’élément correspondant coïncident.
• Le tableau n’est pas initialisé car la valeur d’un élément du tableau n’est utilisée dans le
programme (totalisation et affichage) que lorsqu’il a déjà été chargé par la saisie de l’utilisateur.
Lionel Barlatey, 2001 , 2015
7.5
7.4
TABLEAU MULTIDIMENSIONNEL
Les tableaux multidimensionnels se définissent de façon analogue aux tableaux unidimensionnels, à ceci près
qu'il faut une paire de crochets pour chaque indice.
La définition d’un tableau multidimensionnel admet la syntaxe suivante :
<Type> <Nom du tableau>[Taille indice 1][Taille indice2] … [Taille indice n]
Taille indice 1, Taille indice 2, …, Taille indice n sont des expressions entières
dont la valeur indique le nombre d’éléments sur chaque dimension du tableau.
Si un tableau unidimensionnel peut être considéré comme une liste de valeurs, un tableau à deux dimensions de
m x n éléments peut se représenter sous la forme d’un tableau de valeurs à deux entrées, composé de m lignes
et de n colonnes.
Colonne 1 Colonne 2 Colonne 3
Ligne 1
x[0][0]
x[0][1]
x[0][2]
Ligne 2
x[1][0]
x[1][1]
x[1][2]
Ligne 3
x[2][0]
x[2][1]
x[2][2]
…
…
…
…
Ligne (m-1) x[m-2][0] x[m-2][1] x[m-2][2]
Ligne m
x[m-1][0] x[m-1][1] x[m-1][2]
…
…
…
…
…
…
…
Colonne (n-1) Colonne n
x[0][n-2]
x[0][n-1]
x[1][n-2]
x[1][n-1]
x[2][n-2]
x[2][n-1]
…
…
x[m-2][n-2] x[m-2][n-1]
x[m-1][n-2] x[m-1][n-1]
Tableau à 2 dimensions
Exemples
float table[50][50] ;
/* table est un tableau à 2 dimensions comprenant 50
lignes et 50 colonnes, soit 2500 éléments de type réel. */
char page[24][80] ;
/* page est un tableau à 2 dimensions comprenant 24 lignes et
80 colonnes, soit 1920 éléments du type caractère. */
double valeurs[100][66][255] ;
/* valeurs est un tableau à 3 dimensions qui
peut être vu comme un ensemble de 100 tableaux de 66 lignes et
255 colonnes, soit 1'683’000 éléments réels en double précision. */
Initialisation d’un tableau multidimensionnel
Il est important de prendre garde à l’ordre dans lequel les valeurs initiales sont affectées aux éléments d’un
tableau multidimensionnel. La règle d’affectation des valeurs repose sur le fait que le dernier indice (à savoir
celui de droite) croît le plus rapidement, le premier (celui situé le plus à gauche) étant celui qui croît le plus
lentement. Ainsi les éléments d’un tableau bidimensionnel sont remplis ligne par ligne.
L’instruction
int valeurs[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
correspond au tableau
. Le même tableau peut être défini de la façon suivante :
int valeurs[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
Manipulation de tableaux multidimensionnels
La manipulation des tableaux multidimensionnels est analogue à celle des tableaux à une dimension.
Lionel Barlatey, 2001 , 2015
7.6
Références
[1]
[2]
Byron S. Gottfried, Programmation en C, Coll. Schaum’s, Ed. MacGraw-Hill, 1997
Langage C, Ed. PC Poche, Micro Application, 1998
Révision
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
En quoi un tableau diffère-t-il d’une variable ordinaire ?
Quelles sont les conditions que doivent satisfaire la totalité des éléments d’un tableau ?
Comment les divers éléments d’un tableau sont-ils identifiés ?
Qu’appelle-t-on indices d’un tableau ? Quelles sont les restrictions qui s’appliquent aux indices d’un
tableau ?
Donner un moyen pratique de visualiser des tableaux unidimensionnels, bidimensionnels et
tridimensionnels.
En quoi la définition d’un tableau diffère-t-elle de celle d’une variable ordinaire ?
Citer brièvement les règles de création d’un tableau unidimensionnel.
Quel est l’intérêt de définir des tailles de tableaux au moyen de variables symboliques plutôt qu’avec des
entiers fixes ?
Comment sont initialisés les valeurs des éléments d’un tableau unidimensionnel ? Le tableau doit-il être
entièrement initialisé ?
Quelle est la valeur affectée automatiquement aux éléments d’un tableau qui ne sont pas explicitement
initialisés ?
Décrire la façon la plus courante d’affecter une constante chaîne de caractères à un tableau
unidimensionnel de caractères. Peut-on procéder de façon analogue pour un tableau unidimensionnel de
valeurs numériques ?
Lorsqu’un tableau unidimensionnel de caractères se voit affecter une valeur initiale, quel est le caractère
supplémentaire automatiquement ajouté en fin de chaîne ?
Comment sont employés les tableaux en règle générale ? Est-il possible de manipuler des tableaux entiers
par des instructions uniques, sans avoir à utiliser des boucles ?
Comment définit-on des tableaux multidimensionnels ? Comparer avec la méthode de définition d’un
tableau unidimensionnel.
Enoncer les règles déterminant l’ordre dans lequel sont initialisés les valeurs d’un tableau
multidimensionnel.
Problèmes
1.
Décrire les tableaux engendrés par les instructions suivantes, en indiquant les valeurs qui sont affectées
aux différents éléments du tableau.
a) float c[8] = {2., 5., 3., -4., 12., 12., 0., 8.} ;
b) float c[8] = {2., 5., 3., -4.} ;
c) int z[12] = {0, 0, 8, 0, 0, 6} ;
d) char etat[4] = {‘V’, ‘R’, ‘A’, ‘I’} ;
e) char etat[5] = {‘V’, ‘R’, ‘A’, ‘I’} ;
f) char etat[ ] = ‘’VRAI’’ ;
g) char etat[ ] = ‘’FAUX’’ ;
h) int p[2][4] = {1, 3, 5, 7} ;
i) int p[2][4] = {1, 1, 3, 3, 5, 5, 7, 7} ;
j) int p[2][4] = {
{1, 3, 5, 7},
{2, 4, 6, 8}
} ;
k) int p[2][4] = {
{1, 3},
{5, 7}
} ;
Lionel Barlatey, 2001 , 2015
7.7
l) int c[2][3][4] = {
{
{1, 2, 3},
{4, 5},
{6, 7, 8, 9}
},
{
{10, 11},
{},
{12, 13, 14}
},
} ;
m) char couleurs[3][6] = {
2.
{‘R’, ‘O’, ‘U’, ‘G’, ‘E’} ,
{‘V’, ‘E’, ‘R’, ‘T’},
{‘B’, ‘L’, ‘E’, ‘U’}
} ;
Rédiger la définition de tableau répondant à chacune des situations suivantes :
a) Définir un tableau unidimensionnel de 12 éléments de type entier, appelé c. Affecter les valeurs
initiales 1, 4, 7, 10, …, 34 aux éléments de ce tableau.
b) Définir un tableau unidimensionnel de type caractère, appelé point. Affecter la chaîne ‘NORD’ aux
éléments de ce tableau, en terminant par un caractère nul.
c) Définir un tableau unidimensionnel de 4 éléments , de type caractère, appelé lettres. Affecter les
valeurs initiales ‘N’, ‘S’, ‘E’ et ‘O’ aux éléments de ce tableau.
d) Définir un tableau unidimensionnel de 6 éléments, de type flottant, appelé consts. Affecter les
valeurs initiales suivantes : 0.005
-0.032 1e-6 0.167 -0.3e8 0.015
e) Définir un tableau à deux dimensions de 3 x 4 éléments, de type entier, appelé n. Affecter les valeurs
initiales suivantes :
f)
Définir un tableau à deux dimensions de 3 x 4 éléments, de type entier, appelé n. Affecter les valeurs
initiales suivantes :
3.
Décrire le résultat produit par les 4 programmes suivants :
#include <stdio.h>
void main(void)
{
int a, b = 0 ;
int c[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0} ;
for(a = 0 ; a < 10 ; a++)
if((c[a] % 2) == 0) b = b + c[a] ;
printf(’’%d’’, b) ;
for(a = 0 ; a < 10 ; a++)
if((a % 2) == 0) b = b + c[a] ;
printf(’’%d’’, b) ;
for(a = 0 ; a < 10 ; a++)
b = b + c[a] ;
printf(’’%d’’, b) ;
for(a = 0 ; a < 10 ; a++)
if((c[a] % 2) == 1) b = b + c[a] ;
printf(’’%d’’, b) ;
}
Lionel Barlatey, 2001 , 2015
Auteur
Документ
Catégorie
Без категории
Affichages
0
Taille du fichier
231 Кб
Étiquettes
1/--Pages
signaler