从指针访问成员和强制类型转换之间的优先级

4

如果我有

 typedef struct{
       int i;
 } typeB;

 typeA *p;

那么,指针成员访问和类型转换之间的优先级是什么?
 (typeB *)p->i  

实际上是((typeB *)p)->i还是(typeB *)(p->i)


你的代码存在各种问题,不能编译。是不是指的是 typeA 的相反类型 typeB?那么 p 不是一个指针,你怎么将其强制转换为指针类型呢?第三,看起来你正在试图将一个 int 强制转换为 (typeB*) 类型。 - greedybuddha
如果typeA是一个指针类型,那么这个问题才有意义,但是提问者没有具体说明。 - jxh
有很多方法可以自己找出答案,而不是在 Stack Overflow 上发布问题……例如,你可以尝试一下并查看结果。 - Jim Balter
@JimBalter:提问者可能尝试过,但达不到令人信服的结果(例如,实验代码使用了一个实际上有“i”成员的typeA)。有时候,即使一个饥饿的人愿意钓鱼,他仍然需要学会如何钓鱼。 - jxh
@jxh 许多非常不可能的事情都是可能的...例如,OP根本没有输入这个问题,它只是通信线路中各种量子波动的结果。我的评论仍然有效...简单的C优先级谷歌搜索就足够了,可以得到http://www.isthe.com/chongo/tech/comp/c/c-precedence.html作为第一个搜索结果。 - Jim Balter
@JimBalter:Precedence 是我的修改。OP 使用了“preference”这个术语。 - jxh
2个回答

8
一个运算符优先级表将会显示出 -> 的绑定比类型转换更加紧密。
typedef void *typeA;
typeB b;
typeA a = &b;
(typeB *)a->i;   /* wrong: attempt to dereference a void pointer */
((typeB *)a)->i; /* ok */

下面是完整的运算符优先级表,供您参考。在表格中,列表越高的运算符比列表中较低的运算符更紧密地绑定(因此,一次性表达式运算符的绑定最紧密)。如果在表达式中使用相同优先级的运算符,在模糊的情况下(即未被捕获在像()[]这样的一次性表达式运算符中),则通过遵循结合方向来解决。因此,例如以下表达式:
7 + (3 - 5 * 2 + 15) - 6

按照表格中的顺序进行计算,具体如下:

7 + (3 - 10 + 15) - 6     // evaluate * in ()
7 + (-7 + 15) - 6         // evaluate - in () (it is left of the +)
7 + 8 - 6                 // evaluate + in ()
15 - 6                    // evaluate + (it is left of the -)
9                         // evaluate -

当然,编译器可以用不同的方式执行计算,但其结果必须与遵循优先级规则时所获得的结果相匹配。
Operator Type   Operator(s)                                     Associativity
=============   ===========                                     =============
Primary         () [] . -> expr++ expr--                        left-to-right
Expression 
Operators       
-------------   -----------                                     -------------
Unary           * & + - ! ~ ++expr --expr (typecast) sizeof     right-to-left
Operators       
-------------   -----------                                     -------------
Binary          * / %                                           left-to-right
Operators       + -
                >> <<
                < > <= >=
                == !=
                &
                ^
                |
                &&
                ||
-------------   -----------                                     -------------
Ternary         ?:                                              right-to-left
Operator
-------------   -----------                                     -------------
Assignment      = += -= *= /= %= >>= <<= &= ^= |=               right-to-left
Operators       
-------------   -----------                                     -------------
Comma           ,                                               left-to-right
=============   ===========                                     =============

1
在C语言中,->操作符的优先级高于强制类型转换,即(type name)。
因此,(typeB *)p->i 就是 (typeB *)(p->i)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接