Arrow operator (->) usage in C

匿名 (未验证) 提交于 2019-12-03 01:25:01

问题:

I am currently learning C by reading a good beginner's book called "Teach Yourself C in 21 Days" (I have already learned Java and C# so I am moving at a much faster pace). I was reading the chapter on pointers and the -> (arrow) operator came up without explanation. I think that it is used to call members and functions (like the equivalent of the . (dot) operator, but for pointers instead of members). But I am not entirely sure. Could I please get an explanation and a code sample?

回答1:

foo->bar is equivalent to (*foo).bar, i.e. it gets the member called bar from the struct that foo points to.



回答2:

Yes, that's it.

It's just the dot version when you want to access elements of a struct/class that is a pointer instead of a reference.

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; 

That's it!



回答3:

a->b is just short for (*a).b in every way (same for functions: a->b() is short for (*a).b()).



回答4:

foo->bar is only shorthand for (*foo).bar. That's all there is to it.



回答5:

struct Node {     int i;     int j; }; struct Node a, *p = &a; 

Here the to access the values of i and j we can use the variable a and the pointer p as follows: a.i, (*p).i and p->i are all the same.

Here . is a "Direct Selector" and -> is an "Indirect Selector".



回答6:

I had to make a small change to Jack's program to get it to run. After declaring the struct pointer pvar, point it to the address of var. I found this solution on page 242 of Stephen Kochan's Programming in C.

#include   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; } 

Run this in vim with the following command:

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

Will output:

5 - 14.30 6 - 22.40 


回答7:

#include  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; } 


回答8:

Dot is a dereference operator and used to connect the structure variable for a particular record of structure. Eg :

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

In such way we can use a dot operator to access the structure variable



回答9:

The -> operator makes the code more readable than the * operator in some situations.

Such as: (quoted from the EDK II project)

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;  }; 

The _EFI_BLOCK_IO_PROTOCOL struct contains 4 function pointer members.

Suppose you have a variable struct _EFI_BLOCK_IO_PROTOCOL * pStruct, and you want to use the good old * operator to call it's member function pointer. You will end up with code like this:

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

But with the -> operator, you can write like this:

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

Which looks better?



回答10:

I'd just add to the answers the "why?".

. is standard member access operator that has a higher precedence than * pointer operator.

When you are trying to access a struct's internals and you wrote it as *foo.bar then the compiler would think to want a 'bar' element of 'foo' (which is an address in memory) and obviously that mere address does not have any members.

Thus you need to ask the compiler to first dereference whith (*foo) and then access the member element: (*foo).bar, which is a bit clumsy to write so the good folks have come up with a shorthand version: foo->bar which is sort of member access by pointer operator.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!