在这种情况下,为什么输出不是4?

#include  int main() { int arr[] = {1, 2, 3, 4, 5}; int *p = arr; ++*p; p += 2; printf("%d", *p); return 0; } 

前缀++的优先级大于解除引用,因此, p现在应该指向第二个元素。 因此,当我们添加2时,它应该指向第4个元素,答案应该是4 。 但是,答案是3 ,为什么呢?

在像++*p这样的表达式中,优先级根本不起任何作用。 在此表达式中,内部运算符适用于p (在这种情况下为* )。 外部运算符( ++ )适用于内部运算符的结果。

如果你交换它们以获得*++p ,则++将应用于p ,而*将应用于++p的结果。

每次你有一堆一元/后缀操作符位于操作数的同一侧时,它们以内向外的顺序应用。

对于右侧示例,在p++[i] operator ++适用于p[i]适用于p++的结果。 同时,在p[i]++ operator [i]适用于p++适用于p[i]的结果。

优先权开始在“含糊不清”的情况下发挥作用,如:

  • 一元/后缀运算符与二元运算符,例如

     *p + 2 

    在上述情况下,一元*具有比二元+更高的优先级,导致(*p) + 2

     p->i / 5 

    这里postfix ->优先级高于binary / ,结果为(p->i) / 5

    一般来说,一元/后缀运算符的优先级高于二元运算符。

  • 一元与后缀运算符,即操作数两侧的运算符,例如

     *p++ 

    在上面的例子中,postfix ++优先级高于一元* ,导致*(p++)

     &p->i 

    这里的postfix ->比一元&具有更高的优先级,导致&(p->i)

    一般来说,后缀运算符的优先级高于一元运算符。

  • 各种更具“异国情调”的案例如?:运营商……

p开始指向第一个元素arr[0]

在prefix- ++操作中, p指向( *parr[0] )的元素递增, arr[0]现在包含2而不是1.指针本身不会改变。

p (指针,而不是它指向的元素)然后递增2,所以p指向arr[2] …其值为… 3。

因为第一个操作首先取消引用然后递增一个。 另一个操作将索引从0递增到2

如果输出arr[0 ],您会看到该值已递增。

请参阅运算符 ++ (前缀)和* (取消引用)的优先级 。 它们具有相同的优先权并且位于同一个单元格中。 关于从右到左的关联性。 它们的评估如下:

 ++(*p) 

位于同一单元中的运算符(单元格中可能有多行运算符)在给定方向上使用相同的优先级进行求值。 例如,表达式a = b = c被解析为a =(b = c),而不是因为从右到左的关联性而被解析为(a = b)= c。

工作实例:

 #include  int main() { int arr[] = {1, 2, 3, 4, 5}; int *p = arr; ++*p; p += 2; printf("%d", *p); printf("%d", arr[0]); return 0; } 

输出:

 32 

http://ideone.com/6Xlt5N

表达式++*p中的优先级没有问题,因为没有歧义可以解决。 运算符从操作数向外应用。 也就是说,首先应用*p ,并将++应用于该表达式的结果。 该语言不允许一个操作员在另一个操作员面前跳跃。

例如,在两个运算符都可以应用于同一操作数的情况下,优先规则很重要

 *p++ 

在您的示例中不是这种情况。

关于结果,增量不会影响p ,它继续指向arr的第一个元素,直到用p += 2;递增它为止p += 2; 。 这使p指向arr[2] ,其值为3

让我回答一下:

 ++*p 

首先取消引用然后递增值

 *++p 

递增指针地址然后解除引用。

如果您将程序更改为更详细的模式:

 #include  int main() { int arr[] = {1, 2, 3, 4, 5}; int *p = arr; printf("\n1- %p",p); ++*p; printf("\n2- %d",arr[0]); printf("\n3- %p",p); p += 2; printf("\n4- %p",p); printf("\n5- %d", *p); return 0; } 

您将获得以下输出:

 1- 0x7fff9fc53e30 2- 2 // changed the value pointer points to 2- 0x7fff9fc53e30 // pointer stays the same 3- 0x7fff9fc53e38 4- 3 

当两个operatos可以关联到同一个操作数时,Precednce会解析操作顺序。 例如,在2*x+7中, * over +的优先级将计算的顺序解析为加法前的乘法: (2*x)+7

在您的情况下,只有一个运算符适用于p ,它是一个解除引用运算符: *p 。 预增量运算符用于解除引用的l值: ++(*p)因此优先级在此处无关。

关于你的问题,代码++*p是值*p+1 ,而不是p指向的address 。 正确的代码是++p 。 我希望这可以帮到你。