在哪个优先级中评估此语句?

时间:2015-07-15 22:12:51

标签: c operator-precedence associativity

++*P--;

这是考试中的一个问题,如果P是指向数组中任何元素的指针,请解释这个语句的真正含义。

我甚至写了一个简单的代码来评估它:

  int i;
    int* array = calloc(10, sizeof(int));
    for (i = 0; i < 10; i++) {
        array[i] = i;
        printf("%d,", array[i]);
    }
    int* P = array + 5;
    printf("\n %p", P);
    printf("\n %d", *P);

    ++*P--;
    printf("\n %p", P);
    printf("\n %d \n", *P);
    for (i = 0; i < 10; i++) {
        printf("%d,", array[i]);
    }

但输出让我更加困惑:

0,1,2,3,4,5,6,7,8,9,
 0x100105534
 5
 0x100105530
 4 
0,1,2,3,4,6,6,7,8,9,

看起来它首先取消引用P,然后增加其值,然后减少指针P的值,但为什么呢?

根据来自p53的K&amp; R表2-1(见下图) ++, - 和*(取消引用)从右到左具有相同的优先级和关联性。 因此,第一步应该是{strong> <{>} ,然后取消引用,然后增加解除引用值,我错了吗?

enter image description here

2 个答案:

答案 0 :(得分:3)

你的正确性是正确的

++(*(P--))

但请注意,减量是一个后缀操作:即使首先发生对P的更改,表达式的其余部分也会使用P的旧值。因此,在您的示例中,首先P递减到array+4,但P--的值为array+5,因此array[5]会递增。

答案 1 :(得分:2)

你可以想象这个表达式

++*P--

以下方式

int *tmp = p;
--p;
int value = *tmp;
++value;

这是一个示范程序

#include <stdio.h>

int main( void )
{
    char s[] = "Hello World";
    char *p = s + 6;

    std::printf( "%c\n", ++*p-- );
    std::printf( "%s\n", s );

    p = s + 6;
    char *tmp = p--;
    char value = *tmp;
    ++value;

    std::printf( "%c\n", value );
    std::printf( "%s\n", s );
}

程序输出

X
Hello Xorld
Y
Hello Xorld

输出字符串的不同之处在于表达式++*p--会更改字符串本身,但表达式++value;会更改单独的对象。但逻辑是相似的。

后缀表达式p--具有最高优先级,但在降低之前其值为p的值。

表达式++*p--中的一元运算符++和*从右到左分组。因此,首先将operator *应用于表达式,然后应用operator ++。