在这种情况下,为什么输出不是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
指向( *p
或arr[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
表达式++*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
。 我希望这可以帮到你。