在C中访问指针地址的结构成员

Pra*_*dra 2 c pointers

我正在阅读这本书,我在第 14 章中找到了这个代码片段。

struct kobject *cdev_get(struct cdev *p)
{
    struct module *owner = p->owner;
    struct kobject *kobj;
    if (owner && !try_module_get(owner))
        return NULL;
    kobj = kobject_get(&p->kobj);
    if (!kobj)
        module_put(owner);
    return kobj;
}
Run Code Online (Sandbox Code Playgroud)

我知道这会取消引用 p,然后一个 cdev 指针访问其所有者成员

p->owner // (*p).owner
Run Code Online (Sandbox Code Playgroud)

但是,这是如何工作的?似乎它取消引用 cdev 指针的内存地址然后访问指针本身的 kobj 成员?

&p->kobj // (*(&p)).kobj
Run Code Online (Sandbox Code Playgroud)

我认为指针不仅仅是内存地址,所以我不明白它们如何拥有成员。如果它试图访问指针本身的成员,为什么不直接做p.kobj

pax*_*blo 9

根据p被定义为struct cdev *p,p很大程度上是一个“内存地址”,但这还不是全部——它还附加了一个类型

由于表达式*ptr是“指向的对象ptr”,因此附加了类型,因此您可以在逻辑上执行(*ptr).member.

并且,由于ptr->member与 相同(*ptr).member,所以它也是有效的。

最重要的是,您关于“指针 [不是]比内存地址多得多”的论点是正确的。但他们多一点:-)


就 而言&ptr->member,您似乎将其解读为(&ptr)->member,这是不正确的。

相反,根据 C 优先级规则,它实际上是&(ptr->member),这意味着该结构的成员地址。

这些优先规则实际上是由 ISO C 标准(在本例中为 C11)指定的。来自6.5 Expressions,脚注85

语法指定运算符在表达式求值中的优先级,与本小节的主要小节的顺序相同,最高优先级在前。

而且,由于6.5.2 Postfix operators(位覆盖->)在6.5.3 Unary operators(位覆盖&)之前,这意味着->首先评估。