Opérateur de flèche ( - > ) utilisation en C

J'apprends actuellement C en lisant un bon livre de débutant 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 les membres et les fonctions (comme l'équivalent de la . (dot) opérateur, mais pour les pointeurs au lieu de membres). Mais je ne suis pas entièrement sûr. Je peux avoir une explication et un code l'échantillon?

187
demandé sur Machavity 2010-04-04 20:21:12

11 réponses

foo->bar est équivalent à (*foo).bar, c'est à dire qu'il obtient le membre appelé bar de la structure que foo points.

352
répondu sepp2k 2010-04-04 16:23:03

Oui, c'est ça.

C'est juste la version dot lorsque vous voulez accéder aux éléments d'une structure/classe qui est un pointeur au lieu d'une référence.

struct foo
{
  int x;
  float y;
};

struct foo var;
struct foo* pvar;

var.x = 5;
(&var)->y = 14.3;
pvar->y = 22.4;
(*pvar).x = 6;

C'est ça!

104
répondu Jack 2010-04-04 16:30:19

a->b est juste un peu juste pour (*a).b dans tous les sens (même pour les fonctions: a->b() " est l'abréviation de (*a).b()).

25
répondu Peter Alexander 2010-04-04 16:23:41

foo->bar est seulement un raccourci pour (*foo).bar. C'est tout là est à lui.

15
répondu Matti Virkkunen 2010-04-04 16:23:57

Je voudrais juste ajouter aux réponses le " pourquoi?".

. est un opérateur d'accès de membre standard qui a une priorité supérieure à l'opérateur de pointeur *.

Lorsque vous essayez d'accéder aux 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 première déréférencement avec (*foo), puis accéder à l' élément membre: (*foo).bar, ce qui est un peu maladroit à écrire donc les bons gens ont mis au point une version abrégée: foo->bar qui est une sorte d'accès membre par l'opérateur de pointeur.

8
répondu Lukasz Matysiak 2017-10-20 06:20:46
struct Node {
    int i;
    int j;
};
struct Node a, *p = &a;

Ici pour accéder aux valeurs de i et j on peut utiliser la variable a et le pointeur p comme suit: a.i, (*p).i et p->i sont tous les mêmes.

Ici . est un "Direct Sélecteur" et -> est un "Indirecte Sélecteur".

7
répondu Jayghosh Wankar 2017-02-11 09:22:52

J'ai dû faire un petit changement au programme de Jack pour le faire fonctionner. Après avoir déclaré le pointeur struct pvar, pointez-le vers l'adresse de var. J'ai trouvé cette solution à la page 242 de la programmation de Stephen Kochan en C.

#include <stdio.h>

int main()
{
  struct foo
  {
    int x;
    float y;
  };

  struct foo var;
  struct foo* pvar;
  pvar = &var;

  var.x = 5;
  (&var)->y = 14.3;
  printf("%i - %.02f\n", var.x, (&var)->y);
  pvar->x = 6;
  pvar->y = 22.4;
  printf("%i - %.02f\n", pvar->x, pvar->y);
  return 0;
}

Exécutez ceci dans vim avec la commande suivante:

:!gcc -o var var.c && ./var

Affichera:

5 - 14.30
6 - 22.40
1
répondu Rich Vogt 2015-03-09 01:35:07
#include<stdio.h>

int main()
{
    struct foo
    {
        int x;
        float y;
    } var1;
    struct foo var;
    struct foo* pvar;

    pvar = &var1;
    /* if pvar = &var; it directly 
       takes values stored in var, and if give  
       new > values like pvar->x = 6; pvar->y = 22.4; 
       it modifies the values of var  
       object..so better to give new reference. */
    var.x = 5;
    (&var)->y = 14.3;
    printf("%i - %.02f\n", var.x, (&var)->y);

    pvar->x = 6;
    pvar->y = 22.4;
    printf("%i - %.02f\n", pvar->x, pvar->y);

    return 0;
}
1
répondu Gopal Rao 2015-05-30 11:29:05

L'opérateur -> rend le code plus lisible que l'opérateur * dans certaines situations.

Tels que: (Cité du projet EDK II )

typedef
EFI_STATUS
(EFIAPI *EFI_BLOCK_READ)(
  IN EFI_BLOCK_IO_PROTOCOL          *This,
  IN UINT32                         MediaId,
  IN EFI_LBA                        Lba,
  IN UINTN                          BufferSize,
  OUT VOID                          *Buffer
  );


struct _EFI_BLOCK_IO_PROTOCOL {
  ///
  /// The revision to which the block IO interface adheres. All future
  /// revisions must be backwards compatible. If a future version is not
  /// back wards compatible, it is not the same GUID.
  ///
  UINT64              Revision;
  ///
  /// Pointer to the EFI_BLOCK_IO_MEDIA data for this device.
  ///
  EFI_BLOCK_IO_MEDIA  *Media;

  EFI_BLOCK_RESET     Reset;
  EFI_BLOCK_READ      ReadBlocks;
  EFI_BLOCK_WRITE     WriteBlocks;
  EFI_BLOCK_FLUSH     FlushBlocks;

};

La structure _EFI_BLOCK_IO_PROTOCOL 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 vieux opérateur * pour appeler son pointeur de fonction membre. Vous finirez avec du code comme ceci:

(*pStruct).ReadBlocks(...arguments...)

Mais avec l'opérateur ->, vous pouvez écrire comme ce:

pStruct->ReadBlocks(...arguments...).

Qui semble mieux?

1
répondu smwikipedia 2017-02-11 09:32:49

Dot est un opérateur de déréférence et utilisé pour connecter la variable de structure pour un enregistrement particulier de structure. Par exemple:

struct student
    {
      int s.no;
      Char name [];
      int age;
    } s1,s2;

main()
    {
      s1.name;
      s2.name;
    }

De cette manière, nous pouvons utiliser un opérateur de point pour accéder à la variable de structure

0
répondu divya 2016-02-21 20:04:36
#include<stdio.h>
struct examp{
int number;
};
struct examp a,*b=&a;`enter code here`
main()
{
a.number=5;
/* a.number,b->number,(*b).number produces same output. b->number is mostly used in linked list*/
   printf("%d \n %d \n %d",a.number,b->number,(*b).number);
}

La sortie est 5 5 5

0
répondu prashanth 2018-06-01 07:56:44