指针算术:++*ptr 或 *ptr++?

发布于 2024-10-20 06:27:51 字数 217 浏览 6 评论 0原文

我正在学习 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

空城之時有危險 2024-10-27 06:27:51

由于运算符绑定的方式不同,这些语句会产生不同的结果。特别是,前缀++运算符与*具有相同的优先级,并且它们从右到左关联。因此

++*ptr

被解析为

++(*ptr)

“增加ptr指向的值”。另一方面,后缀 ++ 运算符的优先级高于解引用运算符 *。因此,

*ptr++

这意味着

*(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. Thus

++*ptr

is parsed as

++(*ptr)

meaning "increment the value pointed at by ptr,". On the other hand, the postfix ++ operator has higher precedence than the dereferrence operator *. Thefore

*ptr++

means

*(ptr++)

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 increment x indirectly through ptr. Writing *ptr++ would be dangerous because it would march ptr forward past x, and since x isn't part of an array the pointer would be dangling somewhere in memory (perhaps on top of itself!)

Hope this helps!

〆凄凉。 2024-10-27 06:27:51

接受的答案不正确。后缀 ++ 运算符与取消引用/间接 * 的优先级不同。前缀和后缀运算符具有不同的优先级,并且只有前缀运算符与解引用/间接具有相同的优先级。

正如优先级表所示,后缀++有一个<比取消引用/间接* 优先级更高。因此,*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 of ptr; it increments ptr only as a side effect. The value of the expression is the same as the current value of ptr. 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 of ptr, 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.

ぃ双果 2024-10-27 06:27:51

正如 templatetypedef 所说,但您应该在 *ptr 周围提供括号以确保结果。例如,在我的计算机上,使用 GCC 得到 1606415888,使用 CLang 得到 0:

int x = 19;
int *ptr = &x;
printf("%d\n", *ptr++);
printf("%d\n", *ptr);

并且您预计 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:

int x = 19;
int *ptr = &x;
printf("%d\n", *ptr++);
printf("%d\n", *ptr);

And you expected x to be 20. So use (*ptr)++ instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文