C语言 指针运算:++*ptr 还是 *ptr++?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5209602/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pointer Arithmetic: ++*ptr or *ptr++?
提问by ipkiss
I am learning C language and quite confused the differences between ++*ptrand *ptr++.
我学习C语言和相当混乱之间的差异++*ptr和*ptr++。
For example:
例如:
int x = 19;
int *ptr = &x;
I know ++*ptrand *ptr++produce different results but I am not sure why is that?
我知道++*ptr并*ptr++产生不同的结果,但我不确定为什么会这样?
回答by templatetypedef
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”。另一方面,后缀++运算符比解引用运算符具有更高的优先级*。因此
*ptr++
means
方法
*(ptr++)
which means "increment ptrto 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).
这意味着“递增ptr到它指向的元素之后的元素,然后取消引用它的旧值”(因为后缀++交回指针曾经拥有的值)。
In the context you described, you probably want to write ++*ptr, which would increment xindirectly through ptr. Writing *ptr++would be dangerous because it would march ptrforward past x, and since xisn't part of an array the pointer would be dangling somewhere in memory (perhaps on top of itself!)
在您描述的上下文中,您可能想要编写++*ptr,这将x通过 间接递增ptr。写入*ptr++将是危险的,因为它会ptr向前推进x,并且由于x不是数组的一部分,指针将悬挂在内存中的某处(可能在其自身之上!)
Hope this helps!
希望这可以帮助!
回答by verbose
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 prefixoperator has the same precedence as dereference/indirection.
接受的答案不正确。后缀++运算符与 dereference/indirection 的优先级不同*。前缀和后缀运算符具有不同的优先级,只有前缀运算符具有与取消引用/间接相同的优先级。
As the precedence tableshows, postfix ++has a higherprecedence than dereference/indirection *. So *ptr++gets evaluated as *(ptr++). ptr++evaluates to the current value of ptr; it increments ptronly 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.
作为优先顺序表所示,后缀++具有更高比解引用/间接优先*。所以*ptr++被评估为*(ptr++). ptr++计算为 的当前值ptr;它ptr仅作为副作用增加。表达式的值与 的当前值相同ptr。所以它不会对存储在指针上的值产生任何影响。它只会取消对指针的引用(即,获取存储在那里的当前值,即 19),然后推进指针。在您的示例中,没有定义的值存储在 的新位置ptr,因此指针指向垃圾。现在取消引用它会很危险。
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.
同样如表所示, prefix++与 dereference/indirection 具有相同的优先级*,但由于左右关联性,它被评估为++(*ptr)。这将首先取消对指针的引用(即,获取存储在指向的地址处的值),然后增加该值。即,该值现在将为 20。
The accepted answer is correct about the effects of the two, but the actual mechanism is different from the one given there.
关于两者的影响,公认的答案是正确的,但实际机制与那里给出的机制不同。
回答by Morten Kristensen
As templatetypedef says, but you should provide the parenthesis around *ptrto ensure the outcome. For instance, the following yields 1606415888 using GCC and 0 using CLang on my computer:
正如 templatetypedef 所说,但您应该提供括号*ptr以确保结果。例如,以下在我的计算机上使用 GCC 产生 1606415888,使用 CLang 产生 0:
int x = 19;
int *ptr = &x;
printf("%d\n", *ptr++);
printf("%d\n", *ptr);
And you expected xto be 20. So use (*ptr)++instead.
而你预计x是 20。所以(*ptr)++改用。

