如何评估此C表达式

时间:2014-06-29 22:18:10

标签: c

表达式是:

foo = *p++

我正在寻找可以解释这些事情的示例的指南/参考。

我理解postfix ++的优先级高于间接*,因此表达式被解析为

*(p++)

但是我试图让GNU C reference manual Pg 40中的陈述更清晰,说:

这里p作为表达式的副作用递增,但是foo取值为*(p ++)而不是(* p)++,因为一元运算符从右向左绑定。

4 个答案:

答案 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中有对象qq = *p++

“对象操作”不是与“表达式评估”相同的路径。

答案 3 :(得分:1)

说后缀和一元运算符是右关联的(从右到左绑定)只是表达后缀运算符在C中比一元运算符具有更高优先级这一事实的另一种方式。