Je commence juste avec des pointeurs et je suis un peu confus. Je sais &
signifie l'adresse d'une variable et qui *
peut être utilisée devant une variable de pointeur pour obtenir la valeur de l'objet pointé par le pointeur. Mais les choses fonctionnent différemment lorsque vous travaillez avec des tableaux, des chaînes ou lorsque vous appelez des fonctions avec une copie de pointeur d'une variable. Il est difficile de voir un schéma logique à l'intérieur de tout cela.
Quand dois-je utiliser &
et *
?
RTFM
est inutile, et franchement très grossier. Si vous n'avez pas le temps de répondre, soyez respectueux envers ceux qui prennent le temps de répondre à ces questions. J'aimerais pouvoir @ ceci à "anon" mais évidemment il / elle n'a pas le temps de contribuer de manière significative.Réponses:
Vous avez des pointeurs et des valeurs:
Vous transformez un pointeur en une valeur avec
*
:Vous transformez une valeur en pointeur avec
&
:Edit: dans le cas des tableaux, ils sont traités comme des pointeurs. Si vous les considérez comme des pointeurs, vous les utiliserez
*
pour obtenir les valeurs à l'intérieur d'eux comme expliqué ci-dessus, mais il existe également une autre manière plus courante d'utiliser l'[]
opérateur:Pour obtenir le deuxième élément:
L'
[]
opérateur d'indexation est donc une forme spéciale de l'*
opérateur, et il fonctionne comme ceci:la source
int aX[] = {3, 4}; int *bX = &aX;
int *bX = &aX;
ne fonctionne pas car leaX
retourne déjà l'adresse deaX[0]
(c'est-à-dire&aX[0]
), donc&aX
obtiendrait l'adresse d'une adresse qui n'a aucun sens. Est-ce correct?int aX[] = {3,4};
,int **bX = &aX;
est une erreur.&aX
est de type "pointeur vers le tableau [2] deint
", et non "pointeur vers le pointeur versint
". Plus précisément, le nom d'un tableau n'est pas traité comme un pointeur sur son premier élément pour unaire&
. Vous pouvez faire:int (*bX)[2] = &aX;
Il y a un modèle en traitant des tableaux et des fonctions; c'est juste un peu difficile à voir au début.
Lorsque vous traitez des tableaux, il est utile de se rappeler ce qui suit: lorsqu'une expression de tableau apparaît dans la plupart des contextes, le type de l'expression est implicitement converti de "tableau à N éléments de T" en "pointeur vers T", et sa valeur est définie pour pointer vers le premier élément du tableau. Les exceptions à cette règle sont lorsque l'expression de tableau apparaît comme un opérande soit le
&
ou lessizeof
opérateurs, ou lorsqu'elle est une chaîne littérale utilisé comme un initialiseur dans une déclaration.Ainsi, lorsque vous appelez une fonction avec une expression de tableau comme argument, la fonction recevra un pointeur, pas un tableau:
C'est pourquoi vous n'utilisez pas l'
&
opérateur pour les arguments correspondant à "% s" dansscanf()
:En raison de la conversion implicite,
scanf()
reçoit unechar *
valeur qui pointe vers le début dustr
tableau. Cela est vrai pour toute fonction appelée avec une expression de tableau comme argument (à peu près n'importe laquelle desstr*
fonctions*scanf
et des*printf
fonctions, etc.).En pratique, vous n'appellerez probablement jamais une fonction avec une expression de tableau à l'aide de l'
&
opérateur, comme dans:Un tel code n'est pas très courant; vous devez connaître la taille du tableau dans la déclaration de fonction, et la fonction ne fonctionne qu'avec des pointeurs vers des tableaux de tailles spécifiques (un pointeur vers un tableau de 10 éléments de T est d'un type différent d'un pointeur vers un tableau de 11 éléments de T).
Lorsqu'une expression de tableau apparaît en tant qu'opérande de l'
&
opérateur, le type de l'expression résultante est "pointeur vers un tableau à N éléments de T", ouT (*)[N]
, qui est différent d'un tableau de pointeurs (T *[N]
) et un pointeur vers le type de base (T *
).Lorsque vous traitez des fonctions et des pointeurs, la règle à retenir est la suivante: si vous souhaitez modifier la valeur d'un argument et la refléter dans le code appelant, vous devez passer un pointeur sur la chose que vous souhaitez modifier. Encore une fois, les tableaux jettent un peu d'une clé à molette dans les travaux, mais nous traiterons d'abord les cas normaux.
N'oubliez pas que C transmet tous les arguments de fonction par valeur; le paramètre formel reçoit une copie de la valeur du paramètre réel et toute modification du paramètre formel n'est pas reflétée dans le paramètre réel. L'exemple courant est une fonction d'échange:
Vous obtiendrez la sortie suivante:
Les paramètres formels
x
ety
sont des objets distincts dea
etb
, de sorte que les modifications apportées àx
ety
ne sont pas reflétées dansa
etb
. Puisque nous voulons modifier les valeurs dea
etb
, nous devons leur passer des pointeurs vers la fonction swap:Maintenant, votre sortie sera
Notez que, dans la fonction de swap, nous ne changeons pas les valeurs de
x
ety
, mais les valeurs de quoix
ety
pointer vers . Écrire dans*x
est différent de l'écrire dansx
; nous ne mettons pas à jour la valeur enx
soi, nous obtenons un emplacementx
et mettons à jour la valeur à cet emplacement.Cela est également vrai si nous voulons modifier une valeur de pointeur; si on écrit
alors nous modifions la valeur du paramètre d'entrée
stream
, pas cestream
vers quoi pointe , donc changerstream
n'a aucun effet sur la valeur dein
; pour que cela fonctionne, nous devons passer un pointeur au pointeur:Encore une fois, les tableaux jettent un peu d'une clé à molette dans les œuvres. Lorsque vous passez une expression de tableau à une fonction, ce que la fonction reçoit est un pointeur. En raison de la définition de l'indexation de tableau, vous pouvez utiliser un opérateur d'indice sur un pointeur de la même manière que vous pouvez l'utiliser sur un tableau:
Notez que les objets du tableau ne peuvent pas être affectés; c'est-à-dire que vous ne pouvez pas faire quelque chose comme
vous devez donc être prudent lorsque vous traitez avec des pointeurs vers des tableaux; quelque chose comme
ne fonctionnera pas.
la source
Mettre tout simplement
&
signifie l' adresse de , vous verrez que dans les espaces réservés aux fonctions pour modifier la variable de paramètre comme dans C, les variables de paramètre sont passées par valeur, en utilisant les moyens esperluette pour passer par référence.*
signifie le déréférencement d'une variable de pointeur, ce qui signifie obtenir la valeur de cette variable de pointeur.L'exemple ci-dessus montre comment appeler une fonction
foo
en utilisant le passage par référence, comparer avec ceciVoici une illustration de l'utilisation d'une déréférence
Ce qui précède illustre comment nous avons obtenu l' adresse de
y
et l' avons attribuée à la variable pointeurp
. Ensuite, nous déréférençonsp
en attachant le*
à l'avant de celui-ci pour obtenir la valeur dep
, c'est-à-dire*p
.la source
Oui, cela peut être assez compliqué car le
*
est utilisé à de nombreuses fins différentes en C / C ++.Si
*
apparaît devant une variable / fonction déjà déclarée, cela signifie soit que:*
donne accès à la valeur de cette variable (si le type de cette variable est un type pointeur, ou surchargé l'*
opérateur).*
a la signification de l'opérateur multiplier, dans ce cas, il doit y avoir une autre variable à gauche de la*
Si
*
apparaît dans une déclaration de variable ou de fonction, cela signifie que cette variable est un pointeur:Si
&
apparaît dans une déclaration de variable ou de fonction, cela signifie généralement que cette variable est une référence à une variable de ce type.Si
&
apparaît devant une variable déjà déclarée, il renvoie l'adresse de cette variableDe plus, vous devez savoir que lorsque vous passez un tableau à une fonction, vous devrez toujours également transmettre la taille du tableau de ce tableau, sauf lorsque le tableau est quelque chose comme une chaîne de caractères terminée par 0 (tableau char).
la source
Lorsque vous déclarez une variable de pointeur ou un paramètre de fonction, utilisez *:
NB: chaque variable déclarée a besoin de sa propre *.
Lorsque vous souhaitez prendre l'adresse d'une valeur, utilisez &. Lorsque vous souhaitez lire ou écrire la valeur dans un pointeur, utilisez *.
Les tableaux sont généralement traités comme des pointeurs. Lorsque vous déclarez un paramètre de tableau dans une fonction, vous pouvez tout aussi facilement déclarer qu'il s'agit d'un pointeur (cela signifie la même chose). Lorsque vous passez un tableau à une fonction, vous passez en fait un pointeur vers le premier élément.
Les pointeurs de fonction sont les seules choses qui ne suivent pas tout à fait les règles. Vous pouvez prendre l'adresse d'une fonction sans utiliser &, et vous pouvez appeler un pointeur de fonction sans utiliser *.
la source
Je regardais toutes les explications verbeuses, alors je me suis tourné vers une vidéo de l'Université de Nouvelle-Galles du Sud pour le sauvetage.Voici l'explication simple: si nous avons une cellule qui a une adresse
x
et une valeur7
, la façon indirecte de demander l'adresse de la valeur7
est&7
et la façon indirecte de demander la valeur à l' adressex
est*x
.Donc(cell: x , value: 7) == (cell: &7 , value: *x)
façon à examiner .Une autre il: estJohn
assis à7th seat
.La*7th seat
indiqueraientJohn
et&John
donneraaddress
/ emplacement du7th seat
. Cette explication simple m'a aidé et j'espère qu'elle aidera également les autres. Voici le lien pour l'excellente vidéo: cliquez ici.Voici un autre exemple:
Module complémentaire : initialisez toujours le pointeur avant de les utiliser.Si ce n'est pas le cas, le pointeur pointera vers quoi que ce soit, ce qui pourrait entraîner un plantage du programme car le système d'exploitation vous empêchera d'accéder à la mémoire qu'il sait que vous ne possédez pas.
p = &x;
, nous attribuons au pointeur un emplacement spécifique.la source
En fait, vous avez raison, il n'y a rien de plus à savoir :-)
Je voudrais juste ajouter les bits suivants:
&
prend une variable et vous donne l'adresse,*
prend une adresse et vous donne la variable (ou le contenu).char **p
signifie quep
c'est un pointeur vers un pointeur vers unchar
.Quant aux choses qui fonctionnent différemment, pas vraiment:
\0
).la source
Je pense que vous êtes un peu confus. Vous devriez lire un bon tutoriel / livre sur les pointeurs.
Ce tutoriel est très bon pour les débutants (explique clairement ce
&
que*
sont et sont). Et oui, n'oubliez pas de lire le livre Pointers in C de Kenneth Reek.La différence entre
&
et*
est très claire.Exemple:
la source
Ok, on dirait que votre message a été édité ...
Voyez comment vous pouvez utiliser le
&
pour obtenir l'adresse du début de la structure du tableau? Le suivantfera la même chose.
la source