在下面的示例中运算符 ++ 后跟 -> 的工作

Working of the operators ++ followed by -> in the below example

考虑下面给出的代码段:

#include <stdio.h>

struct s
{
        int x;
        char c;
};

int main()
{
        struct s x[2]={{1,'a'},{2,'b'}};
        struct s * p;
        p=x;
        int a = p++ -> x; //line of doubt
        printf("%d \n",a);
}

以下代码的输出是1,它清楚地表明它实际上被评估为:

int a = ((p++) -> x);

现在我的问题是,我们知道在 C 中,二元 -> 运算符的优先级高于一元 ++ 运算符。但是为什么效果是先分组++再分组->.

作为一个二元运算符,它是否会寻找其左侧的第一个操作数并且它是 p 配对是这样完成的:

int a= *(p++ -> x);

但这包括 pp++ 作为一个块,因此首先考虑 p++,但我觉得这个解释有点含糊。任何人都可以向我解释正确的逻辑以及它,任何人都可以向我推荐任何书,我可以从中练习更多这样的例子。

编辑: 感谢您的回答,实际上我已经从 Dennis Ritchie 等人的 "The C Programming Language" 课本中学习了 C。 al 以及 “C- 完整参考” Hebert Schildt。在这两个文本中,运算符优先级如下所示:

资料来源:“C 编程语言(第 2 版)”,作者 Dennis Ritchie 等。 al(第 53 页)

后缀递增运算符++和通过指针访问成员的运算符->具有相同的优先级,它们从左到右分组。所以首先 p++ 被评估,然后 (p++)->x.

C standard 的第 6.5.2p1 节给出了后缀运算符的以下语法声明:

postfix-expression:
  primary-expression
  postfix-expression [ expression ]
  postfix-expression ( argument-expression-listopt )
  postfix-expression . identifier
  postfix-expression -> identifier
  postfix-expression ++
  postfix-expression --
  ( type-name ) { initializer-list }
  ( type-name ) { initializer-list , }

如果您使用了前缀递增运算符,即 ++p->x,其优先级低于 ->,分组为 ++(p->x)。因此,您最终会从最初指向的对象 p 中获取 x 成员,然后该成员将随着对递增成员求值的表达式递增。