【问题标题】:C struct pointer accessing fieldsC 结构指针访问字段
【发布时间】:2014-11-03 03:04:39
【问题描述】:

我读过,如果我们有一个指向结构类型对象的指针,我们不能使用星号 (*) 访问对象字段,但我们需要使用 ->(如箭头符号)。

现在虽然我读到了它,但我不明白为什么我们不能使用星号,我将尝试提供一个代码示例和一张我如何在内存中可视化结构的图片,以帮助您了解阻止的原因我从理解这个主题。

好的,这是我们的代码:

#include <stdio.h>

typedef struct MyStruct
{
    char c1;
    char c2;
} MyStruct;

int main()
{
    MyStruct s1; // Let's assume s1's address is 0x34A
    s1.c1 = 'A';
    s1.c2 = 'B';
    printf("s1 c1 is %c and c2 is %c.\n", s1.c1, s1.c2);

    MyStruct *p = &s1; // Declaring our pointer to point to s1 address, so p points to 0x34A
    printf("s1 c1 is %c and c2 is %c.\n", p->c1, p->c2); // I know this is the valid way
    printf("s1 c1 is %c.\n", *p.c1); // I don't understand why this would be invalid
    return 0;
}

现在让我试着解释一下为什么我不明白为什么这个语法是无效的。 所以 p 指向 s1 的地址,即 0x34A,正如我所见,这就是我在内存中看到 s1 的方式:

所以我在内存中的想象是 s1 当然有它自己的地址,在我们的示例中是 0x34A,它指向内存中的 c1 地址,然后是 c2 地址。 所以当我这样做时:

printf("s1 c1 is %c.\n", (*p.c1)++, *p.c2);

我认为这是因为我正在通过指针访问指针地址内的值,所以我们正在访问 c1 的值。

但正如我所说的那样,它是无效的,我只是想弄清楚为什么,我试图阅读它,但无法真正找到答案,让我对为什么真的感到满意,所以我'我提供了代码示例和图片,这样你就可以进入我的脑海并尝试看看我为什么在这里想错了。

【问题讨论】:

  • 因为*p.c1 表示您要取消引用c1(它不是指针)。另一方面,(*p).c1 会起作用,但你可以看到它是如何通过手指弯曲来完成的(与简单的 p-&gt;c1 相比)。
  • @Groo 所以基本上 (*p).c1 等同于 p->c1 但只是语法不同?没有其他区别?就像你可以在指向数组的指针中做的那样,例如 *(p + i) 和 p[i] 所以只是不同的语法?
  • 是的,这些表达式是等价的。

标签: c pointers struct


【解决方案1】:

*p.c1 被解析为 *(p.c1) 而不是 (*p).c1

因此,当您执行*(p.c1) 时,您尝试在指针上使用点运算符,但失败了。

【讨论】:

  • so (*p).c1 等价于 p->c1 ?
  • 添加一些背景原因:“.”-运算符在 C 中的优先级高于“*”-运算符。参考:en.cppreference.com/w/c/language/operator_precedence
  • @Akes55 哪个更好用?
  • @johngonidelis:使用p-&gt;c1,这是每个人都会期望的。
【解决方案2】:

这里有一个优先级问题。如果您想这样访问,请选择 (*p).c1。 现在通过执行 (*p),您将到达您的结构,然后是成员。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-31
    • 2011-02-03
    • 2019-07-10
    • 2017-01-04
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 2014-04-29
    相关资源
    最近更新 更多