• Aucun résultat trouvé

Tableau multidimensionnel (matrice, )

11.7.1 Définition d’un tableau à plusieurs dimensions

Il suffit de faire figurer autant d'indices entre crochets [ ] qu'on désire de dimensions.

Appartient à la fonction appelée

tab

2.8e10

reel

Appartient à main

tab[i]

0 1

reel[i]

Variables et désignations

utilisables par la

fonction appelée

Variables et désignations

utilisables par

main

reel

(adresse) 0 1.7e-19 -12.5 10.0 NB_MAX_ELT-1 pointeur

Exemple 60. Définition de tableaux multidimensionnels

Dans la définition d'un tableau à deux dimensions, la première paire de crochets contient le nombre de

lignes, la deuxième paire de crochets précise le nombre de colonnes.

Par exemple, le tableau Ecran (défini par char Ecran[25][80]) est formé de 25 lignes constituées

chacune de 80 caractères. Cette définition réserve une zone mémoire pour 25*80 caractères. Un tableau à deux dimensions équivaut à une matrice :

• le premier indice représente le numéro de ligne ; • le second indice le numéro de colonne.

La notation a[i][j] remplace alors la notation habituelle des matrices aij. Seule différence : les indices des

tableaux du Langage C commencent toujours avec la valeur 0. Mais on n'est pas obligé d'utiliser l'élément d'indice 0 ! Il faut alors surdimensionner le tableau, en ajoutant un élément dans chaque sens :

static short int mat[NB_LIG+1][NB_COL+1]; /* pour ne pas utiliser les indices 0 */

Les tableaux à 3 ou 4 dimensions sont beaucoup plus rares, mais le principe reste le même.

11.7.2 Initialisation, stockage en mémoire

L'initialisation d'un tableau à deux dimensions s'effectue en mettant en évidence les deux « sous-tableaux » qui représentent les lignes :

static short int mat[3][4] = { { 0,1,2,3 }, { 4,5,6,7 }, { 8,9,10,11 } } ;

ce qui équivaut à l’écriture plus lisible :

Exemple 61. Initialisation d’une matrice

Cette initialisation ligne par ligne correspond au stockage en mémoire linéaire suivant : 0, 1, 2, …, 6, 7 En Langage C, les éléments d'un tableau sont rangés dans l'ordre obtenu en faisant varier le dernier indice en premier (celui de la colonne). On obtient donc la succession en mémoire suivante :

mat[0][0] mat[0][1] mat[ligne][colonne] mat[0][2] mat[0][3] mat[1][0] mat[1][1] mat[1][2] mat[1][3]

Cette disposition mémoire correspond à la disposition matricielle habituelle, sauf que la notion de « retour à la ligne » n’existe pas en mémoire :

mat[0][0] mat[0][1] mat[0][2] mat[0][3] /* ligne 0 */

mat[1][0] mat[1][1] mat[1][2] mat[1][3] /* ligne 1 */

#define NB_LIG 100 /* exemples de constantes pour dimensionner les tableaux */ #define NB_COL 10

static short int mat[NB_LIG][NB_COL]; /* la matrice est initialisée à 0 grâce à static */

static double reel[5][3] ; /* 5 lignes, 3 colonnes */

static char Ecran[25][80] ; /* 25 lignes, 80 colonnes */

static float courbe[10][10][10] ; /*tableau à 3 dimensions */

static short int mat[2][4] = {

{ 0, 1, 2, 3 }, { 4, 5, 6, 7 }

11.7.3 Accès à un élément : mat[lig][col]

Un élément du tableau mat à deux dimensions est manipulé à l'aide de l'écriture

mat[lig][col]

où lig et col sont des indices qui commencent à 0.

lig (1er indice) représente la ligne et col (2ème indice) la colonne de l'élément.

mat[lig][col] est une notation claire que vous devez utiliser au lieu de mat[i][j], trop répandu. Dès qu’on atteint deux dimensions, les indices doivent avoir des noms évocateurs : lig, col, i_eleve, i_point, i_sommet, i_mesure…

Attention : comme pour le tableau à une dimension, il n'y a aucun contrôle de dépassement des indices. Ne pas oublier que tous les indices commencent à zéro : le dernier élément d'un tableau défini par short int mat[5][3] est mat[4][2].

On peut ne pas utiliser les indices 0 à condition de surdimensionner de 1 chaque dimension concernée.

Exemple 62. Un programme avec un tableau à deux dimensions

Si mat[lig][col] représente l'élément de ligne lig et de colonne col, la notation mat[lig] désigne l'adresse de

la ligne

mat[lig] = & mat[lig][0]. lig c'est-à-dire l'adresse du premier élément de la ligne lig :

De plus, comme dans le cas monodimensionnel, le nom mat du tableau représente l'adresse du tableau, c'est-à-dire l'adresse de son premier élément : les valeurs numériques de mat et de &mat[0][0] sont égales, bien que leurs types soient différents (mat est un pointeur « constant » sur un tableau, alors que

&mat[0][0] est un pointeur « constant » sur un élément).

#define NBLIG 3 /* nombre de lignes de la matrice */

#define NBCOL 4 /* nombre de colonnes */

void main(void) {

short int lig,col ;

static short int mat[NBLIG][NBCOL] ;

/* Saisie de la matrice : */

for (lig=0 ; lig<NBLIG ; lig++)

for (col=0 ; col<NBCOL ; col++)

{

printf("\n Entrez l'élément (%hd,%hd) : ", lig+1,col+1) ;

scanf("%hd", &mat[lig][col]) ;

}

/* Affichage de la matrice : */

printf("\n\n La matrice saisie est :\n") ; for (lig=0 ; lig<NBLIG ; lig++)

{

for (col=0 ; col<NBCOL ; col++)

printf("\t %hd ", mat[lig][col]) ; printf("\n") ;

}

11.7.4 Transmission d'un tableau multidimensionnel en paramètre

La transmission d'un tableau à plusieurs dimensions en paramètre d'une fonction s'effectue comme pour les tableaux à une dimension, à une exception près. La seule différence est que seule la dimension la plus à

gauche peut être omise dans l'en-tête ou le prototype de la fonction.

Une explication peut être la suivante : pour le compilateur, un tableau multidimentionnel est un tableau unidimentionnel de variables, elles-mêmes de type tableau ; c'est ce premier tableau qui est passé en paramètre et le type des variables qui le composent doit être connu.

Pour les tableaux à deux dimensions et plus, le programmeur non confirmé a intérêt à écrire toutes les dimensions dans le prototype et l’en-tête, sans se poser de questions.

Exemple 63. Transmission en paramètre d'un tableau à deux dimensions

#define NBLIG 5 #define NBCOL 3

/* prototype de fonction avec tableau 2D en paramètre : */

void traiter (short int mat[NBLIG][NBCOL] );

ou

void traiter (short int mat[ ][NBCOL] );

/* ATTENTION : les CROCHETS VIDES sont possibles seulement en 1ère position !! */

//--- void main(void)

{

static short int note[NBLIG][NBCOL] ; /* définition du tableau 2D */

traiter(note); /* appel de fonction avec un argument tableau 2D */

}

//---

/* fonction avec tableau 2D en paramètre : */

void traiter (short int mat[NBLIG][NBCOL] ) ou

void traiter (short int mat[ ][NBCOL]) /*ATTENTION AUX CROCHETS NON VIDES!!*/ {

short int lig,col ;

for (lig=0 ; lig<NBLIG ; lig++)

{

for (col=0 ; col<NBCOL ; col++)

mat[lig][col] = … }

...

12 - Les chaînes de caractères

Une chaîne de caractères est utilisée en informatique pour stocker du texte (mot, phrase…). Outre la manipulation de données textuelles, elle est très utilisée pour effectuer des entrées/sorties : affichage à l’écran ou saisie au clavier, lecture ou écriture dans un fichier texte.

Une chaîne de caractères (string) est une suite de caractères alphanumériques (char) terminée par le

caractère nul (c'est-à-dire de code ASCII 0). Contrairement à d'autres langages, il n'existe pas en Langage C

de type chaîne (string) : une chaîne de caractères est mémorisée dans un tableau de caractères à une

dimension.

Exemple 64. Manipulation de chaînes :