avr 中的一元运算符:未定义的行为?

unary operator in avr: undefined behavior?

我遇到的问题是

voltage = voltage*2/3; voltage *= 2/3;

给出了不同的结果。变量是 uint16_t,在 8 位 AVR 微控制器上是 运行 第一个语句给出了正确的结果,第二个语句总是返回 0

我的一些朋友告诉我一元运算符一般不应该使用,这让我想到,因为我也使用像 PORTC &= ~(1 << csBit); 这样的东西。对于编译,我使用 avr-gcc 如果这可能会给你一个想法。

在此先感谢您的帮助

编辑#1:

好的,我知道 = 不是一元运算符。潜在的区别还在于 '''=''' 从右边开始,而 ''''*, /''' 从左边开始。

我想对于 uint,这两个陈述都不正确,我必须写 voltage = (uint16_t)((float)voltage*(float)2/3)

并感谢@Lundin 指出如何正确回应回复

voltage = voltage*2/3voltage 乘以 2,除以 3,并将结果存储在 voltage.

voltage *= 2/3 将 2 除以 3,将结果乘以 voltage,并将结果存储在 voltage 中。整数除法截断,因此 2/3 产生零。

None 其中是一元运算符。

区别在于voltage = voltage * 2 / 3,电压乘以2再除以3:

 voltage = 5
 5 * 2 = 10
 10 / 3 = 3

而在电压 * = 2 / 3 中,由于您使用的是 uint16_t,因此小数点是 t运行,它首先执行 2/3,结果乘以电压:

 votage = 5
 2 / 3 = 0
 voltage = 5 * 0 = 0

为了避免这种情况,您应该在分配给电压之前以浮点数计算 运行,例如在某处添加“.0”:

 voltage = voltage * 2.0 / 3 = 3
 voltage *= 2.0 / 3 = 3

你被不同的运算顺序和整数运算的组合所困扰。

算术运算符是左结合的,所以

voltage = voltage * 2 / 3;

被解析为

voltage = (voltage * 2) / 3;

您将 voltage * 2 的结果除以 3,而

voltage *= 2 / 3;

等同于

voltage = voltage * (2 / 3);

您将 voltage 乘以 2/3 的结果,即 0

问题不在于*=,问题在于

(a * b) / c != a * (b / c)