22

我正在学习 C 语言,很困惑 和 之间的++*ptr区别*ptr++

例如:

int x = 19;
int *ptr = &x;

我知道++*ptr*ptr++产生不同的结果,但我不确定为什么会这样?

4

3 回答 3

55

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

++*ptr

被解析为

++(*ptr)

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

*ptr++

方法

*(ptr++)

这意味着“ptr在它指向的元素之后递增到元素,然后取消引用它的旧值”(因为后缀++交回了指针曾经拥有的值)。

在您描述的上下文中,您可能想要编写++*ptr,这将x通过ptr. 写入*ptr++会很危险,因为它会ptr前进过去x,并且由于x它不是数组的一部分,因此指针会悬在内存中的某个位置(可能在其自身之上!)

希望这可以帮助!

于 2011-03-06T09:03:50.170 回答
11

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

优先级表所示,后缀++的优先级高于dereference/indirection *。所以*ptr++被评估为*(ptr++)ptr++计算为ptr;的当前值 它ptr仅作为副作用增加。表达式的值与 的当前值相同ptr。所以它不会对存储在指针上的值产生任何影响。它只会取消对指针的引用(即,获取存储在那里的当前值,即 19),然后推进指针。在您的示例中,没有定义的值存储在 的新位置ptr,因此指针指向垃圾。现在取消引用将是危险的。

同样如表所示,前缀++与取消引用/间接具有相同的优先级*,但由于左右关联性,它被评估为++(*ptr)。这将首先取消引用指针(即,获取存储在指向的地址的值),然后增加该值。即,该值现在为 20。

关于两者的影响,公认的答案是正确的,但实际机制与那里给出的机制不同。

于 2016-04-29T00:52:53.960 回答
4

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

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

你预计x是 20 岁。所以请(*ptr)++改用。

于 2011-03-06T09:14:48.150 回答