C 指针算法:++*ptr或*ptr++;?

C 指针算法:++*ptr或*ptr++;?,c,pointers,increment,dereference,operator-precedence,C,Pointers,Increment,Dereference,Operator Precedence,我正在学习C语言,对++*ptr和*ptr++之间的区别感到困惑 例如: int x = 19; int *ptr = &x; 我知道++*ptr和*ptr++会产生不同的结果,但我不知道为什么会这样?这些语句会产生不同的结果,因为运算符绑定的方式不同。特别是,前缀++运算符与*具有相同的优先级,并且它们从右向左关联。因此 ++*ptr 被解析为 ++(*ptr) 意思是“增加ptr,”所指的值。另一方面,后缀++运算符的优先级高于终止运算符*。前边 *ptr++ 意味着 这意味

我正在学习C语言,对
++*ptr
*ptr++
之间的区别感到困惑

例如:

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

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

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

++*ptr
被解析为

++(*ptr)
意思是“增加
ptr
,”所指的值。另一方面,后缀
++
运算符的优先级高于终止运算符
*
。前边

*ptr++
意味着

这意味着“increment
ptr
转到它所指向的元素之后的元素,然后取消引用它的旧值”(因为后缀
++
将指针过去的值交还给它)

在您描述的上下文中,您可能希望编写
++*ptr
,这将通过
ptr
间接增加
x
。写
*ptr++
会很危险,因为它会向前移动
ptr
经过
x
,而且
x
不是数组的一部分,指针会在内存中的某个位置(可能在它的顶部!)


希望这有帮助

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

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

你期望
x
是20岁。因此,请改用
(*ptr)+

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

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

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


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

@templatetypedef,如果您要执行printf(“%d”,*ptr++)。它将首先在ptr中包含的位置打印值,然后增加ptr。@Algorithmist-这是正确的;我想我的答案涵盖了这一点。我应该澄清一下以使其更明确吗?@templatetypedef我认为*和++具有相同的优先级,但由于它们的关联性是从L到R,这正在发生。当你说++绑定比*@本能更紧密时,你的意思是一样的吗?@institute:不,后一种形式甚至远不等同于
*(ptr++)
@institute指针算法适应指向类型的大小,因此
ptr+sizeof(数据类型)
实际上将移动超过
sizeof(数据类型)*sizeof(数据类型)
字节。看见[注:示例是编译为C而不是C++,因为 > XC< /Cord>命令行选项。]你不认为第一个打印()应该打印19这是比选择的更好的答案。此外,中的注释2解释了为什么
ptr++
的计算结果为
ptr
*ptr
返回l值。因此,
++*ptr
绝对会修改
ptr
x
)所指向对象的值。当然,您是对的。对不起,谢谢。编辑。几个月来,昏昏欲睡的大脑在一个完全准确的答案中引入了一个错误。
int x = 19;
int *ptr = &x;
printf("%d\n", *ptr++);
printf("%d\n", *ptr);