tha*_*ude 7 c side-effects operator-precedence associativity
我的问题是关于以下代码行,摘自“ The C Programming Language”第二版:
*p++->str;
Run Code Online (Sandbox Code Playgroud)
该书说,这行代码在访问任何str指向后都会递增p。
我的理解如下:
优先级和关联性表示运算符的评估顺序为
后缀增量运算符++产生一个值(即其操作数的值),并且具有在下一个序列点(即以下;)之前递增此操作数的副作用。
优先级和关联性描述运算符被评估的顺序,而不是运算符的操作数被评估的顺序。
我的问题:
我的问题是关于此表达式中最高优先级运算符(->)的求值。我认为,评估此运算符意味着先评估两个操作数,然后应用该运算符。
从->运算符的角度来看,左操作数是p还是p ++?我了解这两个返回相同的值。
但是,如果第一个选项是正确的,我会问“如何评估->运算符而忽略++的存在”。
如果第二个选项是正确的,我会问“在这种情况下,是否不对->进行评估,然后要求对一个较低优先级的运算符++进行评估(并且++的评估要在->之前完成)”?
要理解该表达式,*p++->str您需要了解其*p++工作原理,或者通常了解后缀增量如何在指针上工作。
在的情况下*p++,p指向的位置的值在指针增加之前被取消引用p。
n1570-§6.5.2.4/ 2:
后缀++运算符的结果是操作数的值。副作用是,操作数对象的值增加了(即,向其添加了适当类型的值1)。[...]。在更新操作数存储值的副作用之前,对结果的值计算进行排序。
在情况下*p++->str,++并->具有相同的优先级高于*运营商。将根据*((p++)->str)运算符优先级和关联性规则将此表达式括起来。
这里的一个重要说明是优先级和关联性与评估顺序无关。因此,尽管++具有较高的优先级,但不能保证p++将首先进行评估。这意味着表达式p++(在表达式中*p++->str)将按照上述标准引用的规则进行求值。(p++)->str将访问str成员p点,然后解引用其值,然后p在最后一个序列点与下一个序列点之间的任何时间递增的值。
后缀++和->具有相同的优先级。a++->b解析为(a++)->b,即++先完成。
*p++->str; 执行如下:
该表达式解析为*((p++)->str)。->是元后缀运算符,即->foo是所有标识符的后缀运算符foo。后缀运算符的优先级最高,其后是前缀运算符(例如*)。关联性并不真正适用:只有一个操作数,只有一种将其与给定运算符“关联”的方法。
p++被评估。这将产生(旧)值,p并安排将更新设置p为p+1,该更新将在下一个序列点之前的某个点发生。调用此表达式的结果tmp0。
tmp0->str被评估。这等效于(*tmp0).str:它取消引用tmp0,该引用必须是指向结构或联合的指针,并获取str成员。调用此表达式的结果tmp1。
*tmp1被评估。此取消引用tmp1,它必须是一个指针(指向完整类型)。调用此表达式的结果tmp2。
tmp2将被忽略(该表达式在void上下文中)。在此之前,我们已经达到;并且p必须已经增加。