C 引用相同地址的算术指针

C 引用相同地址的算术指针,c,pointers,assignment-operator,order-of-execution,C,Pointers,Assignment Operator,Order Of Execution,我正在努力理解以下操作: B是变量,Pt1和Pt2指向&B 减量是在矫揉造作之后完成的,所以按照我的逻辑应该是68,但我的IDE给了我69,有人能解释一下吗 提前感谢。您给出的代码会创建未定义的行为!除去指针方面,您基本上是这样做的: B = B--; 无法一致解决此问题,因为您正在为B分配69的值,然后递减后B。那么,答案是什么:赋值还是后减量 对于您的平台/IDE,编译器使用“临时”变量完成了如下操作: // Initial value of B is 69 temp = B--; //

我正在努力理解以下操作:

B是变量,Pt1和Pt2指向&B

减量是在矫揉造作之后完成的,所以按照我的逻辑应该是68,但我的IDE给了我69,有人能解释一下吗


提前感谢。

您给出的代码会创建未定义的行为!除去指针方面,您基本上是这样做的:

B = B--;

无法一致解决此问题,因为您正在为
B
分配
69
的值,然后递减后
B
。那么,答案是什么:赋值还是后减量

对于您的平台/IDE,编译器使用“临时”变量完成了如下操作:

// Initial value of B is 69
temp = B--; // temp is 69 and B is now 68
B = temp;   // B now has the value of 69!
但是,您不能依赖这种“解释”——或者跨不同的编译器,或者甚至在同一个编译器的不同位置使用类似的代码


顺便说一句,您应该将代码作为文本发布,格式化为代码块。

C标准6.5对这种现象给出了一种神秘的解释:

如果标量对象上的副作用相对于同一标量对象上的不同副作用或使用同一标量的值进行的值计算未排序 对象,则行为未定义。如果存在多个允许的订单 表达式的子表达式,如果这样一个未排序的边 效果发生在任何订单中

  • 本例中的“标量对象”是指指向的原始变量
  • 本例中的“值计算”是取消引用任一指针。它们指向同一个变量
  • 在这种情况下,“副作用”意味着修改变量。
    =
    赋值和
    --
    运算符都是副作用
赋值运算符不指定其操作数的求值顺序(6.5.16“操作数求值不按顺序排列”)。未指定
*Pt2
发生在
*Pt1--
之前或之后

这意味着编译器必须同时更新同一变量两次。由于这不是一个定义良好的场景,编译器可能会生成错误的代码。可以显示奇怪值甚至崩溃的代码。这被称为未定义的行为——一种使程序处于无法再依赖确定性行为或预测任何结果的状态的错误

避免这种情况的简单方法是遵循以下最佳实践规则:


切勿在同一表达式中使用++或--运算符和其他运算符。

“那么,哪个给出了答案:赋值或后减量?”以先计算的为准。没有办法从逻辑上对此进行推理,因为没有理由不确定求值顺序,如C++17所示。然而,C委员会坚持认为,C语言必须继续被破坏,因此该命令尚未确定。为了回答这个问题,你需要指出标准,你不能基于逻辑推理来写答案,因为语言不是理性的。也就是说,像
B=B--
这样的代码当然也不是理性的。欢迎使用堆栈溢出。请尽快阅读该页面,并访问描述和的链接。提供必要的详细信息,包括您的代码、编译器警告和相关错误(如果有),这里的每个人都可以帮助您解答问题。