Retour Suite Index

9.3.4. Pointeurs et tableaux à deux dimensions

L'arithmétique des pointeurs se laisse élargir avec toutes ses conséquences sur les tableaux à deux dimensions. Voyons cela sur un exemple:

Exemple

Le tableau M à deux dimensions est défini comme suit:


int M[4][10] = {{ 0, 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}};

Le nom du tableau M représente l'adresse du premier élément du tableau et pointe (oh, surprise...) sur le tableau M[0] qui a la valeur:


               {0,1,2,3,4,5,6,7,8,9}.

L'expression (M+1) est l'adresse du deuxième élément du tableau et pointe sur M[1] qui a la valeur:


               {10,11,12,13,14,15,16,17,18,19}.

Explication

Au sens strict du terme, un tableau à deux dimensions est un tableau unidimensionnel dont chaque composante est un tableau unidimensionnel. Ainsi, le premier élément de la matrice M est le vecteur {0,1,2,3,4,5,6,7,8,9}, le deuxième élément est {10,11,12,13,14,15,16,17,18,19} et ainsi de suite.

L'arithmétique des pointeurs qui respecte automatiquement les dimensions des éléments conclut logiquement que:

M+I désigne l'adresse du tableau M[I]

Problème

Comment pouvons-nous accéder à l'aide de pointeurs aux éléments de chaque composante du tableau, c.à-d.: aux éléments M[0][0], M[0][1], ... , M[3][9] ?

Discussion

Une solution consiste à convertir la valeur de M (qui est un pointeur sur un tableau du type int) en un pointeur sur int. On pourrait se contenter de procéder ainsi:

Mauvaise solution


int M[4][10] = {{ 0, 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}};
int *P;
P = M;   /* conversion automatique */

Cette dernière affectation entraîne une conversion automatique de l'adresse &M[0] dans l'adresse &M[0][0]. (Remarquez bien que l'adresse transmise reste la même, seule la nature du pointeur a changé).

Cette solution n'est pas satisfaisante à cent pour-cent: Généralement, on gagne en lisibilité en explicitant la conversion mise en oeuvre par l'opérateur de conversion forcée ("cast"), qui évite en plus des messages d'avertissement de la part du compilateur.

Solution

Voici finalement la version que nous utiliserons:

Bonne solution


int M[4][10] = {{ 0, 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}};
int *P;
P = (int *)M;  /* conversion forcée */

Dû à la mémorisation ligne par ligne des tableaux à deux dimensions, il nous est maintenant possible traiter M à l'aide du pointeur P comme un tableau unidimensionnel de dimension 4*10.

Exemple

Les instructions suivantes calculent la somme de tous les éléments du tableau M:


int M[4][10] = {{ 0, 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}};
int *P;
int I, SOM;
P = (int*)M;
SOM = 0;
for (I=0; I<40; I++)
     SOM += *(P+I);

Attention !

Attention!

Lors de l'interprétation d'un tableau à deux dimensions comme tableau unidimensionnel il faut calculer avec le nombre de colonnes indiqué dans la déclaration du tableau.

Exemple

Pour la matrice A, nous réservons de la mémoire pour 3 lignes et 4 colonnes, mais nous utilisons seulement 2 lignes et 2 colonnes:


int A[3][4];
A[0][0]=1;
A[0][1]=2;
A[1][0]=10;
A[1][1]=20;

Dans la mémoire, ces composantes sont stockées comme suit :

L'adresse de l'élément A[I][J] se calcule alors par:

A + I*4 + J

Conclusion

Pour pouvoir travailler à l'aide de pointeurs dans un tableau à deux dimensions, nous avons besoin de quatre données:

a) l'adresse du premier élément du tableau converti dans le type simple des éléments du tableau

b) la longueur d'une ligne réservée en mémoire
(- voir déclaration - ici: 4 colonnes)

c) le nombre d'éléments effectivement utilisés 1dans une ligne
(- p.ex: lu au clavier - ici: 2 colonnes)

d) le nombre de lignes effectivement utilisées
(- p.ex: lu au clavier - ici: 2 lignes)

Retour Suite Index