Allocation dynamique
Nous revenons une fois de plus sur l’utilisation du tas pour gérer des tableaux de taille variable. Après avoir mentionné l’existence de tableaux bidimensionnels de taille fixe, nous détaillons l’allocation dynamique1 déjà vue en 7.4.2 et expliquons enfin les pointeurs, du moins partiellement. A travers l’exemple des matrices (et des images en TP) nous mélangeons structures et allocation dynamique. Il s’agira là de notre structure de donnée la plus complexe avant l’arrivée tant attendue – et maintenant justifiée – des objets…
Tableaux bidimensionnels
Principe Il existe en C++ des tableaux à deux dimensions. Leur utilisation est similaire à celle des tableaux standards : – Il faut utiliser des crochets (lignes 1 et 4 du programme ci-dessous). Attention : [i][j] et non [i,j]. – L’initialisation est possible avec des accolades (ligne 5). Attention : accolades imbriquées. – Leurs dimensions doivent être constantes (lignes 6 et 7).
1 int A[2][3]; 2 for (int i=0;i<2;i++) 3 for (int j=0;j<3;j++) 4 A[i][j]=i+j; 5 int B[2][3]={{1,2,3},{4,5,6}}; 6 const int M=2,N=3; 7 int C[M][N];
Limitations Vis-à-vis des fonctions, les particularités sont les mêmes qu’en 1D : – Impossible de retourner un tableau 2D. – Passage uniquement par variable. 1c’est-à-dire l’allocation de mémoire dans le tas avec new et delete.
Tableaux bidimensionnels
Allocation dynamique
mais avec une restriction supplémentaire : On est obligé de préciser les dimensions d’un tableau 2D paramètre de fonction. Impossible donc de programmer des fonctions qui peuvent travailler sur des tableaux de différentes tailles comme dans le cas 1D (cf 4.3.1). C’est très restrictif et explique que les tableaux 2D ne sont pas toujours utilisés. On peut donc avoir le programme suivant :
// Passage de paramètre
double trace(double A[2][2]) {
double t=0;
for (int i=0;i<2;i++)
t+=A[i][i];
return t;
}
// Le passage est toujours par référence..
void set(double A[2][3]) {
for (int i=0;i<2;i++)
for (int j=0;j<3;j++)
A[i][j]=i+j;
}
double D[2][2]={{1,2},{3,4}};
double t=trace(D); 19 double E[2][3];
set(E);
mais il est impossible de programmer une fonction trace() ou set() qui marche pour différentes tailles de tableaux 2D comme on l’aurait fait en 1D :
// OK
void set(double A[],int n,double x)
{
for (int i=0;i<n;i++)
A[i]=x;
}
// NON!!!!!!!!!!!!!!!
// double A[][] est refusé
void set(double A[][],double m,double n,double x)
{
for (int i=0;i<m;i++) 10 for (int j=0;j<n;j++)
A[i][j]=x;
}