箭头运算符( – >)在C中的使用
我目前正在学习C语言,通过阅读一本好书,名为“21天教你C”(我已经学过Java和C#,所以我正在以更快的速度发展)。 我正在阅读关于指针的章节,并且 – >(箭头)操作符出现而没有解释。 我认为它被用来调用成员和函数(就像。(点)运算符的等价物,而不是成员的指针)。 但我不完全确定。 我可以请一个解释和代码示例?
foo->bar
等同于(*foo).bar
,即它从foo
指向的结构中获得名为bar
的成员。
对,就是那样。
当你想要访问一个结构/类的指针而不是参考的时候,这只是点的版本。
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;
而已!
a->b
只是(*a).b
简写(*a).b
函数相同: a->b()
是(*a).b()
)的简写。
foo->bar
只是(*foo).bar
简写。 这就是它的全部。
struct Node { int i; int j; }; struct Node a, *p = &a;
这里访问i
和j
的值我们可以使用variablesa
和指针p
如下: ai
, (*p).i
和p->i
都是一样的。
这里 是“直接select器”, ->
是“间接select器”。
我不得不对Jack的程序做一个小改动,让它运行。 在声明结构指针pvar之后,将它指向var的地址。 我在Stephen Kochan的C程序devise第242页find了这个解决scheme。
#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; }
在vim中用下面的命令运行它:
:!gcc -o var var.c && ./var
会输出:
5 - 14.30 6 - 22.40
#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; }
Dot是一个解引用运算符,用于连接特定结构logging的结构variables。 例如:
struct student { int s.no; Char name []; int age; } s1,s2; main() { s1.name; s2.name; }
以这种方式,我们可以使用点运算符来访问结构variables
在某些情况下, ->
运算符使得代码比*
运算符更具可读性。
如:(引自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; };
_EFI_BLOCK_IO_PROTOCOL
结构包含4个函数指针成员。
假设你有一个variablesstruct _EFI_BLOCK_IO_PROTOCOL * pStruct
,并且你想使用好的旧的*
运算符来调用它的成员函数指针。 你会得到这样的代码:
(*pStruct).ReadBlocks(...arguments...)
但是用->
运算符,你可以这样写:
pStruct->ReadBlocks(...arguments...)
。
哪个更好看?
我只是将答案join“为什么?”。
.
是具有比*
指针操作符更高优先级的标准成员访问操作符。
当你试图访问一个struct的内部函数,并将其写成*foo.bar
,编译器会想要一个'foo'(这是内存中的一个地址)的'bar'元素,显然这个地址没有任何成员。
因此,你需要让编译器首先解引用whith (*foo)
,然后访问成员元素: (*foo).bar
,这有点笨拙,所以好人们想出了一个简写版本: foo->bar
指针运算符是类的成员访问的foo->bar
。