为什么指针使用->而不是.?

3

可能是重复问题:
为什么C语言有->和.的区别?

假设我有这个结构体:

struct movies
{
    string title;
    int year;
} my_movie, *ptrMovie;

现在我这样访问my_moviemy_movie.year = 1999;。现在要访问指针,必须这样做:ptrMovie->year = 1999; 为什么指针使用->运算符,而普通数据类型使用.运算符?它们不能都使用.运算符吗?

因为这会造成混淆吗?不同的操作符需要使用不同的运算符。 - jldupont
4
为什么C语言有指针和数组这两个不同的概念?在C语言中,指针和数组都是非常重要的数据结构。尽管它们之间存在一些相似之处,但它们代表了不同的概念。指针表示一个地址,可以用来访问内存中的特定位置。通过指针,我们可以直接操作内存。指针还可以被用于动态分配内存,因为它们可以指向任何类型的内存空间。数组是一组具有相同类型的元素的集合,可以通过索引来访问它们。数组通常在编译时就被分配了固定大小的内存空间,因此它们的内存分布是静态的。由于这个原因,数组比指针更快速地进行访问。虽然指针和数组在某些情况下可以互换使用,但它们通常代表不同的编程范式。理解它们之间的区别对于正确使用它们非常重要。 - CB Bailey
抱歉,当我搜索时它没有出现。对不起。 - Bob Dylan
我认为“重复”是一个C问题,而不是C++问题,但C++语法之所以像现在这样,很大程度上是因为C也是这样做的。其他问题中的一些答案也涉及到了C++的兼容性。 - CB Bailey
说实话,如果我们考虑的是C++而不是C,另一个原因是 operator-> 需要与运算符 operator. 区别开来。对于实现智能指针类,operator-> 必须可重载以委托到所指向的对象,但 operator. 必须是独立且不可重载的,以允许访问智能指针对象本身的方法。 - jamesdlin
3个回答

9

点运算符(.)用于访问结构体的成员,只能操作结构体变量。 如果您想对指针执行此操作,您需要先解引用指针(使用*),然后访问成员(使用.)。类似以下代码:

(*ptrMovie).year = 1999
< p > -> 运算符是对此的简写。< /p >

". 运算符用于访问结构体的成员,只能在结构体变量上操作。" 真的吗?那类成员变量怎么样? - Glen
@Noufal,是的,但问题标记为C++,它既有结构体也有类。 - Glen
1
Glen,除了它们的定义之外,结构体和类之间没有区别。 - avakar
@Glen。是的。我的错。我对C++不是很熟悉,这也限制了我的答案。不过你的评论澄清了这一点。谢谢。 - Noufal Ibrahim
@Glen:class 关键字创建一个结构体。然而,有些类不是结构体,它们是联合体,并且成员访问运算符也可以用于这些类。 - Ben Voigt
显示剩余3条评论

4
. 运算符仅适用于结构体或类。指针不是结构体或类,因此您需要对指针进行解引用,以获取它所指向的结构体/类,如下所示。
(*ptrMovie).year

成员运算符.的优先级高于解引用运算符*,因此您需要在括号中包含解引用操作。或者您可以这样做。
ptrMovie->year

两者是等价的。'->'运算符是对指针进行解引用,然后访问结构体成员的一种快捷方式。在我的意见中,这种方式打字更少,使用起来更加友好。显然,大多数人都同意我的看法,因为这是我所见过的大多数代码中从指向结构体的指针访问结构体成员的标准方式。当您需要进行多级间接访问时,您会特别感激这种差异:

ptrToStruct->memberPtr->subMemberPtr->subsubPtr->subsubsubPtr->x

(*(*(*(*(ptrToStruct).memberPtr).subMemberPtr).subsubPtr).subsubsubPtr).x

这两个语句是等价的,但第一个更易于处理。


1
“.”仅适用于结构体?真的吗?类呢? - Glen
除了默认的保护(结构体为public,类为private),在C++中类和结构体是可以互换使用的。 - KeithB
@KeithB,是的,我知道。然而答案暗示了另外一种情况。也许我的评论在澄清时不够清晰。 - Glen
是的...我应该说“结构体或类”即使在C++中它们在功能上是相同的东西。 - A. Levy
union 怎么样?实际上,它适用于所有类(这些类是由 classstructunion 类键引入的类型)。 - Ben Voigt

2
如果它们都使用“.”,那么你如何区分指针和实际对象? 对我来说:
->

这让我想起了一个指向某个东西的箭头,所以我认为使用->很好。

与其输入(*myPointer).,使用myPointer->更加简单。


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