表达式是:
foo = *p++
我正在寻找可以解释这些事情的示例的指南/参考。
我理解postfix ++
的优先级高于间接*
,因此表达式被解析为
*(p++)
但是我试图让GNU C reference manual Pg 40中的陈述更清晰,说:
这里p作为表达式的副作用递增,但是foo取值为*(p ++)而不是(* p)++,因为一元运算符从右向左绑定。
答案 0 :(得分:4)
GNU引用具有误导性(恕我直言);从语言的角度来看,它与从左到右无关(反之亦然)。 *
C语言标准没有根据优先级或关联性(从左到右或从右到左)定义事物;这些仅仅是由定义的语法暗示的。 Postfix ++
被归类为后缀表达式,而不是一元表达式:
postfix-expression: primary-expression [...] postfix-expression ++ postfix-expression -- [...] unary-expression: postfix-expression ++ unary-expression -- unary-expression unary-operator cast-expression [...] unary-operator: & * + - ~ !
上述制作规则的互动意味着您的示例被解释为*(p++)
。
然而,在非标准中,原因是由于优先权而非关联性(这对于一元运算符没有意义)。
*实际上,后缀运算符实际上是从左到右,这与所声称的相反。
答案 1 :(得分:4)
在C / C ++中,Prefix ++(或Prefix - )和dereference(*)运算符的优先级相同,Postfix ++(或Postfix - )的优先级高于Prefix ++和*。
如果p是指针,则* p ++等效于*(p ++)(因为后缀具有更高的优先级)
++ * p相当于++(* p)(Prefix ++和*都是右关联的。)
* ++ p相当于*(++ p)(Prefix ++和*都是右关联的)。
您可以看到以下2个程序,以澄清您的疑问。
计划1
#include<stdio.h>
int main()
{
char arr[] = "overflow";
char *p = arr;
++*p;
printf(" %c", *p);
getchar();
return 0;
}
Output: p
计划2
#include<stdio.h>
int main()
{
char arr[] = "overflow";
char *p = arr;
*p++;
printf(" %c", *p);
getchar();
return 0;
}
Output: v
答案 2 :(得分:2)
OP询问“如何评估”表达式*p++
。
有一点是优先权,另一件事是评价
表达式p++
增加变量p
的值,但表达式的值是p
具有的“旧”值。
例如,考虑p
是用于分析字符串的char指针:
char s[] = "0123456789!";
char *p = s;
char q;
p = s; // Here *p == '0'
q = *p++ // Here q == '0' but *p == '1'
虽然优先规则意味着*p++
与*(p++)
相同,但*p++
的值为s[0]
,尽管p == &s[1]
仍然存在。{br> />
更准确地说,表达式的值与*p
相同。
在这种情况下,“副作用”指的是对对象执行的操作,在这种情况下,我们在表达式p
中有对象q
和q = *p++
。
“对象操作”不是与“表达式评估”相同的路径。
答案 3 :(得分:1)
说后缀和一元运算符是右关联的(从右到左绑定)只是表达后缀运算符在C中比一元运算符具有更高优先级这一事实的另一种方式。