Mon opinion très personnelle est que les images avec des flèches pointant de cette façon ou qui rendent les pointeurs plus difficiles à comprendre. Cela les fait ressembler à des entités abstraites et mystérieuses. Ils ne sont pas.
Comme tout le reste de votre ordinateur, les pointeurs sont des nombres . Le nom "pointeur" est juste une manière sophistiquée de dire "une variable contenant une adresse".
Par conséquent, permettez-moi de faire bouger les choses en expliquant comment un ordinateur fonctionne réellement.
Nous avons un int
, il a le nom i
et la valeur 5. Ceci est stocké en mémoire. Comme tout ce qui est stocké en mémoire, il a besoin d'une adresse, sinon nous ne pourrions pas la trouver. Disons qu'il i
se termine à l'adresse 0x12345678 et que son copain j
avec la valeur 6 se termine juste après. En supposant un processeur 32 bits où int vaut 4 octets et les pointeurs sont 4 octets, alors les variables sont stockées dans la mémoire physique comme ceci:
Address Data Meaning
0x12345678 00 00 00 05 // The variable i
0x1234567C 00 00 00 06 // The variable j
Nous voulons maintenant pointer sur ces variables. Nous créons un pointeur vers int int* ip1
, et un int* ip2
. Comme tout dans l'ordinateur, ces variables de pointeur sont également allouées quelque part en mémoire. Supposons qu'ils se retrouvent aux adresses adjacentes suivantes en mémoire, immédiatement après j
. Nous définissons les pointeurs pour qu'ils contiennent les adresses des variables précédemment allouées: ip1=&i;
("copier l'adresse de i dans ip1") et ip2=&j
. Ce qui se passe entre les lignes est:
Address Data Meaning
0x12345680 12 34 56 78 // The variable ip1(equal to address of i)
0x12345684 12 34 56 7C // The variable ip2(equal to address of j)
Donc, ce que nous avons obtenu, c'était encore quelques morceaux de mémoire de 4 octets contenant des nombres. Il n'y a pas de flèches mystiques ou magiques en vue.
En fait, rien qu'en regardant une image mémoire, nous ne pouvons pas dire si l'adresse 0x12345680 contient un int
ouint*
. La différence réside dans la manière dont notre programme choisit d'utiliser le contenu stocké à cette adresse. (La tâche de notre programme est en fait juste de dire au CPU quoi faire avec ces nombres.)
Ensuite, nous ajoutons encore un autre niveau d'indirection avec int** ipp = &ip1;
. Encore une fois, nous obtenons juste un morceau de mémoire:
Address Data Meaning
0x12345688 12 34 56 80 // The variable ipp
Le modèle semble familier. Encore un autre morceau de 4 octets contenant un nombre.
Maintenant, si nous avions un vidage mémoire de la petite RAM fictive ci-dessus, nous pourrions vérifier manuellement où ces pointeurs pointent. Nous regardons ce qui est stocké à l'adresse de la ipp
variable et trouvons le contenu 0x12345680. Quelle est bien sûr l'adresse où ip1
est stockée. Nous pouvons aller à cette adresse, vérifier le contenu là-bas et trouver l'adresse de i
, puis enfin nous pouvons aller à cette adresse et trouver le numéro 5.
Donc, si nous prenons le contenu de ipp, *ipp
nous obtiendrons l'adresse de la variable pointeur ip1
. En écrivant, *ipp=ip2
nous copions ip2 dans ip1, c'est équivalent à ip1=ip2
. Dans les deux cas, nous obtiendrions
Address Data Meaning
0x12345680 12 34 56 7C // The variable ip1
0x12345684 12 34 56 7C // The variable ip2
(Ces exemples ont été donnés pour un processeur big endian)
ipp
lors de sa définition, afin que votre question soit complète ;-)