Rappel sur tableau multidimensionnel
Accès aux éléments d'un tableau
Rappelons que l'accès à l'élément n[i][j]
d'un tableau « float tab[N1][N2]
» est calculé automatiquement selon la formule \(tab+\left (i* N2 +j\right )*sizeof\left ( float \right )\). Cette formule montre bien que la dimension de niveau 2 (N2) est nécessaire.
Seule la dimension du plus haut niveau n'est pas nécessaire dans le calcul d'accès d'un élément.
Remarque :
Dans l'exercice précédent, il est dit que la déclaration float (*n)[]
est acceptée. n est un pointeur sur un tableau de taille inconnue. Ainsi, l'absence de dimensions ne nous permettra pas d'utiliser l'arithmétique des pointeurs sur n. Les opérateurs, comme ++, [], applicables sur un pointeur utilisent cette arithmétique. La déclaration introduit donc des contraintes sur l'utilisation des tableaux à 2 dimensions.
Organisation des données
Ces impossibilités résultent de la nature de notre problème qui induit une dimension des sous-tableaux variable.
La seule possibilité est float **n
qui peut être également exprimée par float *n[]
.
Toutefois, l'emploi de ces déclarations nous oblige à revoir la définition de la fonction puisqu'il suppose une organisation différente des données.
La figure ci-dessous présente une différence d'implantation entre des déclarations comme tab[4][3] et **pt. On voit que pour le tableau bidirectionnel, il n'y a pas d'adresse enregistrée comme c'est le cas pour pt.
Remarque :
Pour le tableau bidirectionnel, les lignes étant stockées les unes derrière les autres, il est aisé de comprendre qu'une déclaration comme tab[][3] nous permet de travailler avec un nombre de lignes variable.
Méthode : Une nouvelle organisation des données
Les inconnues sur le nombre de notes par élève, comme sur le nombre d'élèves, nous imposent de ne plus utiliser un tableau à 2 dimensions.
Précédemment, nous avons introduit un paramètre pour indiquer le nombre de moyennes à réaliser. La transmission des notes doit passer par les pointeurs, avec une déclaration float *ptnotes[]
. Ceci nous amène à établir un parallèle avec les paramètres optionnels de la fonction main (int argc
et char *argv[]
).
Proposons une organisation semblable pour les notes :
Utilisation d'une organisation des données semblable à l'organisation des paramètres de la fonction main dont le 2e paramètre optionnel est char
*argv[]
.ptnotes donnera accès à un tableau, de taille nb, de pointeurs contenant les accès aux groupes de notes par élève.
Les notes de chaque élève seront dans des espaces contigus. Pour la localisation de ces groupes de notes, 2 possibilités :
À l'image de l'organisation de argv, l'organisation peut être dispersée où chaque groupe est à une position indépendante de l'ensemble,
Nous prévoyons un grand espace unique où seront stockés les groupes de notes. Les différents pointeurs donnent accès à la 1ère note de chaque élève.
Pour connaître le nombre de notes par élève :
Utiliser un tableau contenant pour chaque élève le nombre de notes. Ce tableau devra être construit et transmis à la fonction,
Dans l'organisation dispersée, soit insérer en tête de groupe de notes le nombre de notes entrant dans le calcul, soit terminer la série par un témoin symbolisant la fin de la série. Par exemple, une valeur négative ou hors proportion (10000) peut remplir cette fonction,
Dans un espace unique, les 2 options précédentes sont envisageables. Nous pouvons y ajouter l'utilisation du pointeur d'accès aux notes de l'élève suivant pour arrêter la sommation. Cette dernière solution nécessite soit un traitement particulier pour le dernier élève, soit l'introduction d'un pointeur supplémentaire au 1er niveau dont l'utilité se limitera à indiquer la fin de série du dernier élève.
Pour le nombre de notes de chaque élève, nous écartons le tableau supplémentaire ainsi que l'insertion de l'information en tête de série pour garder une organisation semblable à chaque composante de argv, avec un témoin égal à -1.
Toutefois, pour stocker les séries de notes, nous utiliserons un espace commun.