【问题标题】:Dereference a Member of struct Struct_type with (*variable).member vs *variable.member使用 (*variable).member 与 *variable.member 取消引用结构 Struct_type 的成员
【发布时间】:2020-02-05 00:28:01
【问题描述】:

给定:

typedef struct Person_struct { char name[10]; int age; } Person;
Person bob;

void makePerson(Person *human) { 
   strcpy((*human).name, "Bob Bee");
   (*human).age = 36;
}

然后取消引用采用一般形式:

(*variable).member //variable could be bob, member could be age

我知道成员访问运算符. 优先于*,所以我们首先使用括号取消引用变量。我真的不明白为什么这是必要的。

*variable.member 首先对成员访问运算符进行操作以获取指向 struct_type 的指针,然后 .member 将添加 sizeof(member) 以获取要引用的位置,这实际上似乎更直观。

但是(*variable).member 的正确形式非常不直观。目前尚不清楚(*variable) 实际返回的“值”是什么,也不清楚如何从返回的内容中访问该成员。

我的问题是:

当使用(*variable).member 而不是*variable.member 时,内存中发生了什么?

我看到了this,但它没有回答我的问题。

【问题讨论】:

  • 你为什么不用->

标签: c pointers struct


【解决方案1】:

你不能使用*variable.member的原因是因为这个例子中的变量是一个指针,而不是一个结构体,你不能在指针上使用成员访问操作符。我们有一个单独的运算符 -> 用于对取消引用的指针进行成员访问:

strcpy(human->name, "Bob Bee");

【讨论】:

  • 他的问题是“内存中发生了什么......”:)
【解决方案2】:

我知道成员访问运算符. 优先于*,所以我们首先使用括号取消引用变量。我真的不明白为什么这是必要的。

您刚刚说过:成员访问运算符. 优先于取消引用运算符*。如果您问为什么. 具有优先权,那只是设计选择。

正确的形式 (*variable).member 非常不直观

我会说这很烦人,而不是不直观。事实上,这是一个非常常见的操作,以至于有一个操作员来处理它。当你有一个指向它的指针时,你可以使用-> 操作符来访问它的字段。

human->age = 36
// same as
(*human).age = 36

当使用(*variable).member 而不是*variable.member 时,内存中发生了什么?

(*variable).member 与“取variable 中的地址并取消引用它,然后取刚刚获得的结构的member 字段”相同。

执行*variable.member 与说“获取结构variablemember 字段内的地址,然后取消引用它”相同。如果variable 是指针,那当然是错误的。

【讨论】:

    【解决方案3】:

    好问题!

    这在很大程度上取决于您的编译器如何处理符号的含义

    例如,在 C++ 中,语句(*variable).member(*variable) 可以解释为实际对象的reference

    Person bob;
    Person* ptr = &bob;
    
    Person& ref = *ptr;
    

    引用可以用作其上下文中的实际对象。

    但是,从编译器的角度来看,(*variable) 仅在编译过程中的immediate step 处有意义。

    在最后一步(二进制),(*variable) 失去了意义。

    唯一剩下的就是(*variable).member被解释为variable->member。也就是说,取指针variable,使用Person类型解引用它,从Person结构的原型中获取实际属性。

    例子:

    struct Person {
        char* name;
        int age;
    };
    Person bob;
    printf("%d\n", bob.age);
    

    一个可能的二进制代码可以是

    1. advance stack pointer about `sizeof(Person) = 16 bytes` (determined at compile time for 64bit machine). Top of the stack now contains the value of object bob
    2. put the last 8 bytes on top of the stack into `printf` function. (You are gonna learnt more about this later)
    

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-10
      • 1970-01-01
      • 2016-08-13
      • 2022-07-29
      • 1970-01-01
      • 2013-09-05
      • 1970-01-01
      相关资源
      最近更新 更多