Pages du site
Cours actuel
Participants
Généralités
Section 2
Section 3
Nom de tableauxEn C, nom[i] est équivalent à *(nom+i). dans cette notation, nom désigne l’adresse du 1er élément (1er octet) du tableau nome, nom+i donne l’adresse de l’élément d’indice i, et *(nom+i) donne la valeur de cet élément. Voici l’exemple d’un tableau de caractères imprimé en procédant de deux manières différentes :
Ce programme donne : ogorogor. La seconde manière est plus efficace Le fait que le nom d’un tableau dans une expression est converti en une valeur entraîne que :
Il y a deux exceptions à cette conversion :
Quand on déclare un objet tableau, on n’a pas, en machine, de pointeurs sur le 1er élément.Ne pas se laisser tromper par les notation suivantes :
Dans les deux cas, on a un tableau, dont la taille est calculée par le compilateur (8 caractères, les sept de bonjour, plus le caractère \0).
Le langage C est tout de même compliqué : 2 façons différentes d’introduire un tableau de caractères, sachant qu’avec la fonction calloc, il y a une 3ème façon. Le programme suivant, faisant intervenir deux fichiers compilés séparément, comporte une erreur dont l’effet est indéfini.
La fonction f tente un accès via le pointeur tab qui contient la valeur 4 (contenu du premier élément) et non l’adresse du tableau tab. L’affectation entre tableaux est interdite, pas celle entre pointeursSoit deux variables chaines de caractères déclarées de la façon suivante : Comme message 2 et message 1 sont des ponteurs, l’instruction
affecte à message2 le contenu de la varaiable message1, c’est une affectation d’adresse. La chaîne de caractères « bonjour » n’existe qu’en un seul exemplaire en mémoire, elle n’a pas été dupliquée. Soit deux autres variables déclarées sous forme de tableaux de caractères : Comme chaine 1 et chaine2 sont des tableaux, l’instruction suivante :
sera refusée par le compilateur ;, puisque le nom du tableau désigne l’adresse du premier octet de ce tableau, c’est donc une adresse constante. Passage de tableaux en paramètresOn dispose de deux façons de passer un tableau en paramètres. Nous donnons deux version de la fonction C strcpy, copiant une chaîne de caractères t dans une autre (copie profonde, la totalité de chaîne est copiée).
Notez la concision de la version b. Dans la version a, on déclare en paramètres 2 tableaux de caractères dont on ne connait pas la taille. Dans la version b, on déclare un pointeur sur un caractère. Dans les 2 cas, c’est l’adresse du tableau qui est passé. Il n’y a pas besoin d’utiliser l’opérateur & (adresse de). Les deux versions de la fonction s’appellent de la même façon : strcpy (chaine1, chaine2) ;
Notez l’utilisation de const pour indiquer que le contenu de la chaîne t n’est pas modifié. Notez aussi que les deux versions fonctionnent quelque soit la taille des tableaux (c’est d’ailleurs inquiétant). Rien n’empêche de déborder du tableau, paramètre effectif, correspondant au paramètre s. Le langage C fait confiance au programmeur.
Les tableaux multidimensionnelsLa déclaration et l’utilisationEn C, les tableaux multidimensionnels sont en fait des tableaux de tableaux. La déclaration se fait de la manière suivante :
Il est possible d’utiliser un typedef définissant un alias (synonyme) de type tableau :
Rangement en mémoire et calcul d’adresse.Les tableaux multidimensionnels sont rangés en mémoire de façon contiguë (le n+1ème indice variant plus vite que le nième). Pour un tableau à deux dimensions, cela correspond à un rangement de ligne. Un tableau à plusieurs dimensions est un cas particulier de tableau. Un nom d’objet tableau est donc converti en l’adresse de son premier élément, et l’expression tabint [i][j] est équivalente à *(*(tabint+i)+j). En fait le compilateur, rencontrant un accès aux éléments d’indice i et j du tableau toto tab [N] [M] effectuera le calcul d’adresse suivant, ce qui nécessite 2 additions et deux multiplications :
donnant la taille d’une ligne et sizeof(toto) la taille d’un élément. L’initialisation
Une liste incomplète est automatiquement complétée de 0. On peut aussi faire l’initialsation de la façon suivante :
Atention, ne pas confondre :
et
Le tableau de pointeurs sur des tableauxDans un texte, les lignes sont en général de longueurs variables. Si ces lignes doivent rangées, bout à bout, dans un grand tableau de caractères, il est intéressant de pouvoir accéder directement à une ligne du texte. Pour résoudre ce problème, on peut utiliser un tableau dont les éléments pointeraient sur le premier caractère de chaque ligne. C’est le but de la déclaration suivante qui crée un tableau de nbr_lignes pointeurs de caractères :
Les tableaux de pointeurs sont aussi intéressants (dans le cas où les lignes sont de tailles égales) quand on ne connaît pas à la compilation les dimensions du tableau. On utilise alors l’allocation dynamique (calloc). On peut aussi noter que l’accès à un élément est plus rapide dans le cas d’un tableau de pointeurs. Comparaison entre pointeurs de tableaux et tableaux multidimensionnels Il en faut pas confondre un tableau de pointeurs et un tableau à deux dimensions. Prenons comme exemple :
Les représentations en mémoire sont distinctes dans les deux cas. On peut remarquer qu’un tableau de pointeurs sur tableaux peut occuper moins de place mémoire qu’un tableau à 2 dimensions, lorsque les lignes ont des tailles différentes. Le « miracle » est que pour ces deux tableaux, l’accès à un élément (un caractère) se faite de la même façon, car la notation tableau_de_saison [i] [j] est équivalente à *( tableau_de_saison [i]+j) où tableau_de_saison [i] donne l’adresse du premier élément du ième tableau. Mais l’accès à un élément en utilisant en utilisant un tableau de pointeurs est plus rapide. Si on veut que les lignes se suivent en mémoire, ….. Paramètres du programme principal |