指针算术:++*ptr 或 *ptr++?
我正在学习 C 语言,并且很困惑 ++*ptr
和 *ptr++
之间的区别。
例如:
int x = 19;
int *ptr = &x;
我知道 ++*ptr
和 *ptr++
会产生不同的结果,但我不确定为什么会这样?
I am learning C language and quite confused the differences between ++*ptr
and *ptr++
.
For example:
int x = 19;
int *ptr = &x;
I know ++*ptr
and *ptr++
produce different results but I am not sure why is that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于运算符绑定的方式不同,这些语句会产生不同的结果。特别是,前缀
++
运算符与*
具有相同的优先级,并且它们从右到左关联。因此被解析为
“增加
ptr
指向的值”。另一方面,后缀++
运算符的优先级高于解引用运算符*
。因此,这意味着
“递增
ptr
以转到它所指向的元素之后的元素,然后取消引用其旧值”(因为 postfix++
将指针的值交回)曾经有过)。在您描述的上下文中,您可能想要编写
++*ptr
,它将通过ptr
间接递增x
。编写*ptr++
会很危险,因为它会将ptr
向前推进到x
之前,并且由于x
不是其中的一部分数组的指针将悬挂在内存中的某个位置(可能在其自身之上!)希望这会有所帮助!
These statements produce different results because of the way in which the operators bind. In particular, the prefix
++
operator has the same precedence as*
, and they associate right-to-left. Thusis parsed as
meaning "increment the value pointed at by
ptr
,". On the other hand, the postfix++
operator has higher precedence than the dereferrence operator*
. Theforemeans
which means "increment
ptr
to go to the element after the one it points at, then dereference its old value" (since postfix++
hands back the value the pointer used to have).In the context you described, you probably want to write
++*ptr
, which would incrementx
indirectly throughptr
. Writing*ptr++
would be dangerous because it would marchptr
forward pastx
, and sincex
isn't part of an array the pointer would be dangling somewhere in memory (perhaps on top of itself!)Hope this helps!
接受的答案不正确。后缀
++
运算符与取消引用/间接*
的优先级不同。前缀和后缀运算符具有不同的优先级,并且只有前缀运算符与解引用/间接具有相同的优先级。正如优先级表所示,后缀
++
有一个<比取消引用/间接*
优先级更高。因此,*ptr++
的计算结果为*(ptr++)
。ptr++
计算出ptr
的当前值;它增加ptr
只是作为副作用。表达式的值与ptr
的当前值相同。所以它不会对指针存储的值产生任何影响。它只会取消引用指针(即获取存储在那里的当前值,即 19),然后前进指针。在您的示例中,ptr 的新位置没有存储定义的值,因此指针指向垃圾。现在取消引用它会很危险。同样如表所示,前缀
++
与解引用/间接*
具有相同的优先级,但由于左右关联性,它的计算结果为++ (*ptr)
。这将首先取消引用指针(即获取存储在指向的地址处的值),然后递增该值。即,该值现在为 20。关于两者的影响,接受的答案是正确的,但实际机制与此处给出的不同。
The accepted answer is not correct. It's not the case that the postfix
++
operator has the same precedence as dereference/indirection*
. The prefix and postfix operators have different precedence, and only the prefix operator has the same precedence as dereference/indirection.As the precedence table shows, postfix
++
has a higher precedence than dereference/indirection*
. So*ptr++
gets evaluated as*(ptr++)
.ptr++
evaluates to the current value ofptr
; it incrementsptr
only as a side effect. The value of the expression is the same as the current value ofptr
. So it won't have any effect on the value stored at the pointer. It will merely dereference the pointer (i.e., get the current value stored there, which is 19), then advance the pointer. In your example there is no defined value stored at the new position ofptr
, so the pointer is pointing to garbage. Dereferencing it now would be dangerous.Also as the table shows, prefix
++
has the same precedence as dereference/indirection*
, but because of right-left associativity, it gets evaluated as++(*ptr)
. This will first dereference the pointer (i.e., get the value stored at the address pointed to) and then increment that value. I.e., the value will now be 20.The accepted answer is correct about the effects of the two, but the actual mechanism is different from the one given there.
正如 templatetypedef 所说,但您应该在
*ptr
周围提供括号以确保结果。例如,在我的计算机上,使用 GCC 得到 1606415888,使用 CLang 得到 0:并且您预计
x
为 20。因此请改用(*ptr)++
。As templatetypedef says, but you should provide the parenthesis around
*ptr
to ensure the outcome. For instance, the following yields 1606415888 using GCC and 0 using CLang on my computer:And you expected
x
to be 20. So use(*ptr)++
instead.