Je sais que c’est très fondamental, mais c’est un peu déroutant pour moi.
J'ai lu:
un pointeur n'est rien d'autre qu'une adresse adresse , et un pointeur variable est juste une variable qui peut stocker une adresse .
Lorsque nous stockons l’adresse d’une variablei
dans la variable de pointeurp
, nous disons quep
pointe versi
.
int i, *p = &i;
p
pointe sur i
.
Pour accéder à l'objet pointé par un pointeur, nous utilisons l'opérateur *
(indirection).
Si
p
est un pointeur then*p
représente l'objet sur lequelp
pointe actuellement.
Maintenant, je suis confus que je devrais appeler p
- pointeur ou variable pointeur ?
Supplémentaire: Un pointeur est-il toujours identique à une adresse?
La différence entre une valeur de pointeur et une variable de pointeur est illustrée par:
int swap_int(int *i1, int *i2)
{
int t = *i1;
*i1 = *i2;
*i2 = t;
}
int main(void)
{
int v1 = 0;
int v2 = 37;
int *p2 = &v2;
printf("v1 = %d, v2 = %d\n", v1, v2);
swap_int(&v1, p2);
printf("v1 = %d, v2 = %d\n", v1, v2);
return 0;
}
Ici, p2
est une variable de pointeur; c'est un pointeur sur int
. D'autre part, dans l'appel à swap_int()
, l'argument &v1
est une valeur de pointeur, mais il ne s'agit en aucun cas d'une variable de pointeur (dans la fonction appelante). C'est un pointeur sur une variable (et cette variable est v1
), mais écrire simplement &v1
ne crée pas une variable de pointeur. Dans la fonction appelée, la valeur du pointeur &v1
est affectée à la variable de pointeur local i1
et la valeur de la variable de pointeur p2
est affectée à la variable de pointeur local i2
, mais ce n'est pas la même chose que de dire que &v1
est une variable de pointeur ( parce que ce n'est pas une variable de pointeur, c'est simplement une valeur de pointeur).
Cependant, pour de nombreuses raisons, la distinction est floue. Les gens diraient 'p2
est un pointeur' et c'est assez vrai; il s'agit d'une variable de pointeur dont la valeur est une valeur de pointeur. *p2
est la valeur de l'objet pointé par p2
. Vous obtenez le même flou avec 'v1
est une int
'; c'est en fait une variable int
et sa valeur est une valeur int
.
Remplaçons le mot "pointeur" par un type de données qui, espérons-le, est plus familier, comme un int
:
int n = 42;
Ici 42 est une valeur int
, et n
est une variable qui contient une int
. Vous pouvez appeler n
une "variable int
". Un int est un nombre tel que 42 ou -25315685, et une variable int
contient ces nombres. Une fois que vous avez une variable, vous pouvez lui attribuer différents nombres. Rien de déroutant jusqu'à présent?
Un pointeur ressemble à un entier: un nombre. Il s’agit d’un numéro qui identifie un emplacement de mémoire, et si quelque chose est stocké dans cet emplacement de mémoire, vous pouvez l’appeler adresse . Comme un int, un pointeur peut être stocké dans une variable. Une variable qui stocke un pointeur pourrait être appelée une variable de pointeur.
Alors, quelle est la différence entre un pointeur et une variable de pointeur? Le premier est une valeur, comme un nombre, le second stocke ces valeurs. Mais souvent, les gens se réfèrent à des variables par leurs valeurs qu'ils stockent; les gens n'appellent pas n
une "variable int
" mais juste int
, même si, à différentes heures, il peut stocker différentes int
s. Dans ce texte, je vais faire la même chose et parfois écrire un pointeur quand je parle d'une variable de pointeur; j'espère que la distinction sera claire.
Un pointeur est-il toujours une adresse? Ceci est une question sur le sens du mot "adresse" plus que toute autre chose. Un pointeur est toujours une adresse dans le sens où il correspond à un emplacement mémoire d'une manière ou d'une autre, c'est une "adresse" pour cet emplacement mémoire. Mais d’autre part, si l’emplacement mémoire n’est pas accessible au programme ou n’y contient aucun élément utile, s’agit-il vraiment d’une «adresse»?
Examinons maintenant le code suivant:
int *p;
p = &n;
La première ligne déclare une variable de pointeur appelée p
. Les pointeurs pouvant être stockés dans p
sont des emplacements de mémoire pour les données int
; c'est important pour des raisons que nous verrons plus tard. Nous ne donnons toujours aucune valeur à p
; le pointeur qu'il stocke est donc arbitraire. Cela ne stocke certainement l'adresse d'aucun objet utile; il peut même indiquer une zone de mémoire inaccessible au programme.
Dans la deuxième ligne, nous prenons l'adresse de la variable n
avec l'opérateur &
- et l'attribuons à p
. Maintenant, p
stocke l'adresse de n
, l'emplacement de la mémoire où la valeur de n
est stockée.
Que pouvons-nous faire avec un pointeur? Nous pouvons lire et écrire dans l'emplacement de mémoire identifié par le pointeur. Pour ce faire, nous "déréférencons" le pointeur avec l'opérateur *
-, puis (*p)
peut être utilisé comme vous pouvez utiliser n
. Par exemple, vous pouvez écrire une nouvelle valeur dans n
avec ceci:
*p = 123;
C’est à ce stade que nous comprenons mieux pourquoi nous avons besoin de connaître le type de données que p
peut indiquer: sinon vous ne pouvez pas savoir ce que vous pouvez affecter à (*p)
.
Une autre raison pour laquelle il est important de connaître le type de données que p
peut pointer est: arithmétique de pointeur . Par exemple, p+1
est un pointeur sur la int
stockée dans la mémoire juste après n
; si p
était un pointeur sur une grande structure de données, p+1
serait un pointeur sur une structure de données du même type, stockée juste après. Pour cela, le compilateur doit connaître la taille de la cible.
Le jeton p
est une variable de pointeur qui pointe vers une variable i
. Nous pouvons simplement l'appeler un pointeur.
Une déclaration:
int* p;
int i;
p = &i;
déclare p
comme identifiant d'un objet de type int
. Ceci est généralement indiqué de manière plus succincte par 'p is a pointer to i'
. p
peut être utilisé pour faire référence à la variable int i
après expression p = &i
. Pour accéder à la valeur de la variable i
à l'aide du pointeur p
, vous pouvez utiliser l'opérateur de déréférence *
(par exemple *p
). Et i = 10;
équivalent à *p = 10;
.
En outre, remarquez dans l'expression p = &i;
pour lire l'adresse de i
que j'ai utilisé l'opérateur &
également appelé Address of operand
.
Un pointeur est juste une adresse logique (un identifiant avec lequel une variable peut être référencée). La norme C ne définit pas ce qu'est un pointeur en interne ni son fonctionnement en interne.
Vous voudriez lire: Qu'est-ce qu'un pointeur C, sinon une adresse mémoire?
De plus, lisez ceci: Comprendre le but des pointeurs.
Les termes pointeur et variable de pointeur sont souvent utilisés comme synonymes.
Une variable est un endroit pour stocker une valeur. En C, chaque fois que vous utilisez une variable dans un contexte qui nécessite une valeur, la valeur de la variable est extraite. Par conséquent, dire "p" dans ce contexte revient à dire "la valeur de la variable p":
int *q = p; // Copy the value of variable p into the variable q.
// aka: copy p into q.