Je lis un livre intitulé "Teach Yourself C in 21 Days" (j'ai déjà appris Java et C # donc je me déplace à un rythme beaucoup plus rapide). Je lisais le chapitre sur les pointeurs et l' opérateur->
(flèche) est apparu sans explication. Je pense qu'il est utilisé pour appeler des membres et des fonctions (comme l'équivalent de l' opérateur (point), mais pour des pointeurs au lieu de membres). Mais je ne suis pas tout à fait sûr..
Puis-je obtenir une explication et un exemple de code?
Réponses:
foo->bar
est équivalent à(*foo).bar
, c'est- à -dire qu'il obtient le membre appelé àbar
partir de la structure quifoo
pointe vers.la source
->
opérateur n'aurait pas été nécessaire du tout, car il aurait été équivalent à celui beaucoup plus lisiblefoo*.bar
. Tout le gâchis des fonctions de typage avec toutes les parenthèses supplémentaires aurait également été évité.foo*.bar
et les(*foo).bar
deux seraient-ils équivalentsfoo->bar
? Et alorsFoo myFoo = *foo; myFoo.bar
?Oui c'est ça.
C'est juste la version dot lorsque vous souhaitez accéder aux éléments d'une structure / classe qui est un pointeur au lieu d'une référence.
C'est tout!
la source
pvar = &var
?a->b
est juste court(*a).b
dans tous les sens (idem pour les fonctions:a->b()
est court pour(*a).b()
).la source
Je voudrais juste ajouter aux réponses le "pourquoi?".
.
est un opérateur d'accès aux membres standard qui a une priorité plus élevée que l'*
opérateur de pointeur.Lorsque vous essayez d'accéder aux éléments internes d'une structure et que vous l'avez écrit comme
*foo.bar
alors, le compilateur penserait vouloir un élément `` bar '' de `` foo '' (qui est une adresse en mémoire) et, évidemment, cette simple adresse n'a pas de membres.Ainsi, vous devez demander au compilateur de déréférencer d'abord avec
(*foo)
puis accéder à l'élément membre:,(*foo).bar
ce qui est un peu maladroit à écrire, de sorte que les bonnes personnes ont trouvé une version abrégée:foo->bar
qui est une sorte d'accès aux membres par opérateur de pointeur.la source
foo->bar
n'est qu'un raccourci pour(*foo).bar
. C'est tout ce qu'on peut en dire.la source
Ici , l'accès aux valeurs de
i
etj
nous pouvons utiliser la variablea
et le pointeurp
comme suit:a.i
,(*p).i
etp->i
sont tous les mêmes.Voici
.
un "sélecteur direct" et->
un "sélecteur indirect".la source
Je dois également ajouter quelque chose. La structure est un peu différente du tableau car le tableau est un pointeur et la structure ne l'est pas. Donc sois prudent!
Disons que j'écris ce morceau de code inutile:
Ici, le pointeur
ptr
pointe vers l'adresse ( ! ) De la variable de structureaudi
mais à côté de la structure d'adresse a également un morceau de données ( ! )! Le premier membre du bloc de données a la même adresse que la structure elle-même et vous pouvez obtenir ses données en ne déréférençant qu'un pointeur comme celui-ci*ptr
(pas d'accolades) .Mais si vous voulez acess tout autre membre que le premier, vous devez ajouter un code comme
.km
,.kph
,.kg
qui ne sont rien de plus que des compensations à l'adresse de base du bloc de données ...Mais en raison de la priorité, vous ne pouvez pas écrire
*ptr.kg
car l'opérateur d'accès.
est évalué avant l'opérateur de déréférence*
et vous obtiendrez*(ptr.kg)
ce qui n'est pas possible car le pointeur n'a pas de membres! Et le compilateur le sait et émettra donc une erreur, par exemple:Au lieu de cela vous utilisez ce
(*ptr).kg
et vous forcer compilateur 1er déréférencer le pointeur et activez acess au bloc de données et 2 vous ajoutez un décalage (désignateur) de choisir le membre.Vérifiez cette image que j'ai faite:
Mais si vous aviez des membres imbriqués, cette syntaxe deviendrait illisible et a donc
->
été introduite. Je pense que la lisibilité est la seule raison justifiable de l'utiliser, car elleptr->kg
est beaucoup plus facile à écrire qu'à(*ptr).kg
.Maintenant, écrivons ceci différemment afin que vous puissiez voir la connexion plus clairement.
(*ptr).kg
⟹(*&audi).kg
⟹audi.kg
. Ici, j'ai d'abord utilisé le fait qu'ilptr
s'agit d'une "adresse deaudi
" c'est&audi
-à- dire le fait que les opérateurs "référence"&
et "déréférencement"*
s'annulent.la source
J'ai dû apporter un petit changement au programme de Jack pour le faire fonctionner. Après avoir déclaré le pointeur struct pvar, pointez-le sur l'adresse de var. J'ai trouvé cette solution à la page 242 de la programmation de Stephen Kochan en C.
Exécutez cela dans vim avec la commande suivante:
Sortira:
la source
%
pour représenter le nom de fichier actuel. Comme ça:!gcc % && ./a.out
la source
L'
->
opérateur rend le code plus lisible que le*
opérateur dans certaines situations.Tels que: (cité du projet EDK II )
le
_EFI_BLOCK_IO_PROTOCOL
structure contient 4 membres de pointeur de fonction.Supposons que vous ayez une variable
struct _EFI_BLOCK_IO_PROTOCOL * pStruct
et que vous souhaitiez utiliser le bon ancien*
opérateur pour appeler son pointeur de fonction membre. Vous vous retrouverez avec un code comme celui-ci:(*pStruct).ReadBlocks(...arguments...)
Mais avec l'
->
opérateur, vous pouvez écrire comme ceci:pStruct->ReadBlocks(...arguments...)
.Qui a l'air mieux?
la source
la sortie est de 5 5 5
la source
Le point est un opérateur de déréférence et utilisé pour connecter la variable de structure pour un enregistrement particulier de la structure. Par exemple :
De cette façon, nous pouvons utiliser un opérateur point pour accéder à la variable de structure
la source
->
. Cette question a également été répondue depuis 4,5 ans déjà.