指针变量中的 p.a 和 p->a 有什么区别?

3

指针p.a和p->a有什么区别吗?或者它们只是同一件事情。


8
p.a 的代码应该无法运行,你的编译器应该会提示错误或警告。 - RedX
@RedX - 这并不是完全正确的。p 可能是智能指针,而 a 可能是它的某个公共方法/成员。那么,例如,p.operator->() 就会非常好。 - Kiril Kirov
@Kiril 是的,那可能是真的。所以我可以重新表述一下。p.a 对于指针是不起作用的,但是对于重载 operator-> 的实例,p->a 可能会起作用。他也特别询问了当 p 是一个指针时的情况。 - RedX
@Kiril Kirov:你看到了C++标签吗?我没有。在C语言中没有运算符重载或智能指针。 - JeremyP
@JeremyP - 哦,该死,我知道我漏了什么。抱歉,我没有看到这是 C,而不是 C++,我知道在 C 中没有智能指针和运算符重载 (: - Kiril Kirov
5个回答

4
< p > . 运算符实际上是结构体成员访问的运算符。 < /p >
struct Foo
{
    int bar;
    int baz;
} aFoo;

aFoo.bar = 3;

如果你有一个指向结构体的指针(非常常见),你可以使用指针解引用和.运算符来访问其成员。
struct Foo *p;
p = &aFoo;

(*p).baz = 4;

括号是必需的,因为 . 的优先级高于 *。以上代码解引用指向结构体的某个成员非常常见,因此引入了-> 作为一种简写方式。
p->baz = 4; // identical to (*p).baz = 4

如果p是指针,在普通的C语言中你不会看到p.anything,至少在任何可以编译通过的地方不会。然而,在Objective-C中,它被用来表示属性访问,我认为这是一个错误。


@Alan - p = &aFoo,但这里的 * 是因为声明。它等同于:struct Foo *p; p = &aFoo; - Kiril Kirov
@Alan:抱歉。这行声明了一个指针,并将指针初始化为前一个结构变量的地址。我会编辑答案,以使正在发生的事情更加明显。 - JeremyP

3

是的,您不能在指针上执行p.a操作符,因为点操作符需要一个实际的实例,即适当的struct类型的值。

请注意,“在底层”,p->a等同于(*p).a,但更易于键入和阅读。没有人使用后一种形式,但有时它作为理解箭头操作符的方式很方便。


如果p是地址,我们使用p->a或(*p).a这样的语法来理解它,如果p是实例,我们使用p.a或(&p)->a。 - Alan Tam
1
更好的做法是:如果使用指针,则使用 p->a;如果使用实例,则使用 p.a。这是99.9%的情况下的做法。 - RedX

1
尝试使用 (*p).a 或 (&p)->a 语句,其中 p 分别表示指针和实例;-)

0
如果p是一个指针,那么p.a不是有效的语法。

0

这是编译时错误... 只有 p->a 是有效的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接