C语言 C 中的箭头运算符 (->) 用法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2575048/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Arrow operator (->) usage in C
提问by Mohit Deshpande
I am reading a 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) operatorcame 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.
我正在阅读一本名为“在 21 天内自学 C”的书(我已经学习了 Java 和 C#,所以我的学习速度要快得多)。我正在阅读有关指针的章节,->(箭头)运算符没有解释就出现了。我认为它用于调用成员和函数(类似于.(点)运算符,但用于指针而不是成员)。但我不完全确定。
Could I please get an explanation and a code sample?
我能得到解释和代码示例吗?
回答by sepp2k
foo->baris equivalent to (*foo).bar, i.e. it gets the member called barfrom the struct that foopoints to.
foo->bar等价于(*foo).bar,即它获取bar从foo指向的结构中调用的成员。
回答by Hyman
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;
pvar = malloc(sizeof(pvar));
var.x = 5;
(&var)->y = 14.3;
pvar->y = 22.4;
(*pvar).x = 6;
That's it!
就是这样!
回答by Peter Alexander
a->bis just short for (*a).bin every way (same for functions: a->b()is short for (*a).b()).
a->b(*a).b在各方面都只是缩写(功能相同:a->b()是 的缩写(*a).b())。
回答by Lukasz Matysiak
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.barthen 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.
当您尝试访问结构的内部并且您将其编写为*foo.bar这样时,编译器会认为需要 'foo'(这是内存中的地址)的 'bar' 元素,并且显然该地址没有任何成员。
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->barwhich is sort of member access by pointer operator.
因此,您需要要求编译器首先取消引用 whith (*foo),然后访问成员元素:(*foo).bar,写起来有点笨拙,所以好人想出了一个速记版本:foo->bar这是一种通过指针运算符访问成员的方式。
回答by Matti Virkkunen
foo->baris only shorthand for (*foo).bar. That's all there is to it.
foo->bar只是 的简写(*foo).bar。这里的所有都是它的。
回答by Jayghosh Wankar
struct Node {
int i;
int j;
};
struct Node a, *p = &a;
Here the to access the values of iand jwe can use the variable aand the pointer pas follows: a.i, (*p).iand p->iare all the same.
这里访问的价值观i和j我们可以使用变量a和指针p如下:a.i,(*p).i并且p->i都是一样的。
Here .is a "Direct Selector" and ->is an "Indirect Selector".
这.是一个“直接选择器”和->一个“间接选择器”。
回答by 71GA
Well I have to add something as well. Structure is a bit different than array because array is a pointer and structure is not. So be careful!
好吧,我也必须添加一些东西。结构与数组有点不同,因为数组是指针而结构不是。所以要小心!
Lets say I write this useless piece of code:
假设我写了这段无用的代码:
#include <stdio.h>
typedef struct{
int km;
int kph;
int kg;
} car;
int main(void){
car audi = {12000, 230, 760};
car *ptr = &audi;
}
Here pointer ptrpoints to the address (!) of the structure variable audibut beside address structure also has a chunk of data(!)! The first member of the chunk of datahas the same address than structure itself and you can get it's data by only dereferencing a pointer like this *ptr(no braces).
这里的指针ptr指向结构变量的地址(!),audi但在地址结构旁边还有一个数据块(!)!数据块的第一个成员与结构本身具有相同的地址,您可以通过仅取消引用这样的指针*ptr(无大括号)来获取它的数据。
But If you want to acess any other member than the first one, you have to add a designator like .km, .kph, .kgwhich are nothing more than offsets to the base address of the chunk of data...
但是如果你想访问除第一个成员之外的任何其他成员,你必须添加一个像.km,的指示符.kph,.kg它们只不过是数据块基地址的偏移量......
But because of the preceedenceyou can't write *ptr.kgas access operator .is evaluated before dereference operator *and you would get *(ptr.kg)which is not possible as pointer has no members! And compiler knows this and will therefore issue an error e.g.:
但是由于优先级,您不能编写*ptr.kg访问运算符.在取消引用运算符之前进行评估,*并且您会得到*(ptr.kg)这是不可能的,因为指针没有成员!编译器知道这一点,因此会发出错误,例如:
error: ‘ptr' is a pointer; did you mean to use ‘->'?
printf("%d\n", *ptr.km);
Instead you use this (*ptr).kgand you force compiler to 1stdereference the pointer and enable acess to the chunk of dataand 2ndyou add an offset (designator) to choose the member.
相反,您使用它(*ptr).kg并强制编译器第一次取消引用指针并启用对数据块的访问,第二次添加偏移量(指示符)以选择成员。
Check this image I made:
检查我制作的这张图片:
But if you would have nested members this syntax would become unreadable and therefore ->was introduced. I think readability is the only justifiable reason for using it as this ptr->kgis much easier to write than (*ptr).kg.
但是如果你有嵌套成员,这种语法将变得不可读,因此->被引入。我认为可读性是使用它的唯一正当理由,因为它ptr->kg比(*ptr).kg.
Now let us write this differently so that you see the connection more clearly. (*ptr).kg? (*&audi).kg? audi.kg. Here I first used the fact that ptris an "address of audi"i.e. &audiand fact that "reference"&and "dereference"*operators cancel eachother out.
现在让我们换一种方式来写,以便您更清楚地看到这种联系。(*ptr).kg? (*&audi).kg? audi.kg. 在这里,我第一次使用的事实,ptr是一个“地址audi”,即&audi与事实“引用”&和“解引用”*运营商取消了海誓山盟。
回答by prashanth
#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);
}
output is 5 5 5
输出为 5 5 5
回答by Rich Vogt
I had to make a small change to Hyman'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.
我不得不对 Hyman 的程序做一个小改动才能让它运行。声明struct指针pvar后,将其指向var的地址。我在 Stephen Kochan's Programming in C 的第 242 页找到了这个解决方案。
#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;
}
Run this in vim with the following command:
使用以下命令在 vim 中运行它:
:!gcc -o var var.c && ./var
Will output:
将输出:
5 - 14.30
6 - 22.40
回答by Gopal Rao
#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;
}


