|
||
|
Chapitre XXV Les pointeurs sont une des caractéristiques principales du langage C. Dans ce chapitre, nous essayerons de voir comment les utiliser dans nos programmes...
I:\ Un pointeur ? Mais qu'est-ce que c'est que ça ? "Pointeur" ? Mais à ce mot barbare correspond
t'il ? C'est presque la question que je me suis posé quand j'en ai entendu parler
dans la documentation de TIGCC pour la première fois... Un pointeur n'est rien de plus qu'une variable qui contient
une adresse. Cependant, on ne peut pas parler d'une "variable de type pointeur"
de la même façon que nous parlons d'une "variable de type short"
ou d'une "variable de type float"...
En effet, il existe en C plusieurs de type de pointeurs, qui correspondent
aux types de données que l'on pourra trouvé à l'adresse indiquée par ceux-ci... A: Déclaration d'un pointeur : Pour déclarer une variable comme étant un pointeur dans
un programme, il convient d'utiliser ce type de syntaxe : B: Utilisation de l'opérateur & : L'opérateur unaire &
permet d'obtenir l'adresse de la variable placée à sa suite. Ainsi, utiliser
une écriture de ce type : On a dit précédemment qu'un pointeur était une variable
capable de contenir une adresse. Il nous sera donc possible d'effectuer les
opérations suivantes (à titre d'exemple, j'ai ici choisi de travailler avec
des shorts,
mais il est parfaitement possible d'utiliser n'importe quel autre type de variables
!) : C: Utilisation de l'opérateur * : L'opérateur unaire *
joue exactement le rôle inverse de celui que nous venons d'étudier. En effet,
en utilisant une écriture de ce type : Ainsi, si l'on continue de travailler avec l'exemple que
nous avons employé juste au-dessus, on pourra effectuer ces autres instructions
: Réciproquement, effectuer cette instruction : Remarque 1 : Il est possible de
donner deux significations à une écriture du style "*pointeur"... Remarque 2 : Je vous conseille de
ne jamais introduire d'espace entre le symbole "*"
et le nom du pointeur. En effet, bien que ceci soit autorisé par le compilateur
C, cela ne facilite pas la compréhension du code source, en particulier
dans les cas où il faut multiplier la valeur de la variable pointée par le pointeur
par un autre autre nombre. En effet, le symbole qui permet la multiplication
est aussi "*"... D: Quelques "dangers" liés à une mauvaise utilisation de base des pointeurs : 1: Déclaration de plusieurs pointeurs : Vous avez sans doute déjà déclaré plusieurs variable d'un
même type en utilisant une syntaxe du type : 2: Pointeurs et mémoire : Attention : déclarer des pointeurs ne réserve pas d'espace mémoire pour d'éventuelles
données pointées !!! De plus, lorsque vous déclarez un pointeur, l'adresse qu'il
contient est parfaitement imprévisible !
II:\
Opérations avec les pointeurs : A: Opérations possibles : Nous allons voir, dans cette sous-partie, de nombreux exemples
de manipulations simples de pointeurs, qui pourront souvent vous être utiles...
short var_1,
var_2; Voici les différentes manipulations que nous effectuerons (nous considérerons qu'elles se suivent, et donc, que ce que nous avons obtenu lors d'une manipulation est encore valable au moment où nous commençons la manipulation suivante).
var_1 = 111;
// affecte la valeur 111 à la variable var_1.
pointeur_1 = &var_1;
// Le pointeur pointeur_1 pointe à présent sur la variable
var_1. *pointeur_1 = *pointeur2 + 56; // La variable pointée par pointeur_1 prend pour valeur la somme de la valeur de la variable pointée par pointeur_2 et de 56. Cela revient à effectuer l'opération "var_1 = var_2 + 56;"... La variable var_1 a donc à présent pour valeur 222+56 = 278 pointeur_2 = pointeur_1; // pointeur_2 pointe à présent vers la même variable que pointeur_1. Ces deux pointeurs pointent donc à présent tous deux sur la variable var_1.
*pointeur_1 =
*pointeur_2 +
12;
// Ici, on met dans la variable pointée par pointeur_1
la somme de la valeur de la variable pointée par pointeur_2 (la valeur de var_1,
soit 278) et de 12. var_1 vaut donc à présent 278+12 = 290. B: Opérations impossibles : Pendant tout ce chapitre, nous avons vu que lorsque nous
déclarions des pointeurs, il nous fallait préciser le type des données vers
lesquelles ils allaient pointer. Donc, il n'est naturellement pas possible de
"mixer" les variables et pointeurs de types différents, même si, pour
simplifier, les poineturs contiennent tous la même chose, c'est-à-dire une adresse...
III:\ Pointeurs et fonctions : Dans certains cas, quand vous voulez passer en argument d'une fonction des grosses variables (par exemple, une longue chaîne de caractères), et que vous voulez gagner un peu de vitesse, il vous sera bien utile d'utiliser nom pas la chaîne de caractère elle-même, mais plutôt un pointeur vers celle-ci... Cependant, il existe un cas où il est indispensable (à ma
connaissance !) d'utiliser des pointeurs lors de l'appel d'une fonction : il
s'agit du cas où l'on veut que la fonction soit capable de modifier ses paramètres... Voici le code du programme qui correspond à cette fonction ainsi qu'à la fonction _main permettant de l'appeler : #define OPTIMIZE_ROM_CALLS Comme vous pouvez le remarquer, il convient d'utiliser l'opérateur
"*"
dans le prototype de la fonction (ainsi que dans sa déclaration), mais il faut
utiliser l'opérateur "&"
lorsqu'on l'appelle... A présent, vous comprenez peut-être mieux le fonctionnement de certaines fonctions incluses dans les librairies de TIGCC, qui nécessitent qu'on leur passe des pointeurs en argument...
Nous voilà arrivé à la fin de ce chapitre... J'espère que,
maintenant, vous aurez moins de difficultés et de réticences à les employer
dans vos programmes (voire même plus du tout !)... Une fois encore, je ne peux
que vous encourager à parcourir ce chapitre plusieurs fois, à écrire de petits
programmes pour appliquer vos connaissances nouvellement acquises.... |