指向结构的指针上的点运算符

Posted

技术标签:

【中文标题】指向结构的指针上的点运算符【英文标题】:Dot operator on pointer to a struct 【发布时间】:2019-09-19 14:54:57 【问题描述】:

假设我有一个结构

typedef struct list_entry 
    int val;
    int val2;
 list_entry;

和一个指向它的指针

list_entry list;
list_entry* pList = &list;

那么为什么(*pList).val2 给了我存储在list.val2 的值,如果*pList 返回存储在pList 中的地址的值,并且由于pList 持有列表的地址,*pList 应该返回存储在 val 中的数字?提前致谢。

【问题讨论】:

听起来你可以使用good C++ book。将详细介绍指针的工作原理以及取消引用指针的含义。 出于同样的原因list.val2 为您提供val2 而不是val 的值。您只需访问复合数据类型的属性。 您正在访问val2,因此您获得了存储在val2 中的值。这有什么令人惊讶的,为什么您会期望以val 结束? 完全正常,您要求会员 val2 您得到 val2 。但是*((int*)pList)val +1 回复@NathanOliver。您可能混淆了 * 运算符和 * 声明符,或者换句话说,当 * 用于声明指针时,以及 * 用于取消引用指针时。 【参考方案1】:

我们假设 int 是 4 个字节。现在list_entry 至少有 8 个字节。然而pList 只指向这 8 个字节中的第一个。

现在所有这些表达式如何工作?在 C(和 C++ 中)中,编译器会查看整个表达式。 .val2 成员可能是一个 4 字节值,字节偏移量为 4-7。不要担心确切的细节,这是编译器的工作。如果你在valval2 之间插入一个成员,一切都会移动,但编译器仍会跟踪。

所以在(*pList).val2 中,编译器知道将4 个字节添加到pList,然后取出接下来的4 个字节。

请注意,编译器通常对此类数学运算很有帮助。 pList+1 不加 1 个字节,而是 1 * sizeof(list_entry)

【讨论】:

【参考方案2】:

你是对的。 *pList 应该为您提供存储在 pList 中的地址的值。但是值的类型是list_entry*pList 给了你一个list_entry 类型的值,而(*pList).val2val2 字段中的list_entry

现在,如果您将*pList 的值读取为int,那么您将获得字段val 的值。 例如*((int*)pList) TLDR:*pList 确实返回存储在pList 中的地址的值,但值的类型由*pList 的类型决定。

【讨论】:

以上是关于指向结构的指针上的点运算符的主要内容,如果未能解决你的问题,请参考以下文章

指向数组部分的指针。重载 [] 运算符以访问数组的各个部分

类指针

C语言结构体指针成员所指向的变量如何访问?

结构体成员的引用方法

指针在建立链表时的应用

包含指向派生模板类的基类指针的类的赋值运算符和复制构造函数