C 类型系统既微妙又危险。显式转换可能需要也可能不需要。在(uint16_t) nbr & 0x0000FFFF具体情况下,假设 32 位 CPU,强制转换不正确。
你在操作发生之前施放。这意味着操作数nbr将通过强制转换显式转换,然后int通过隐式整数提升立即隐式转换为。结果将是int已签名的类型。在这种情况下无害,但在其他情况下可能会造成麻烦。通过使用不正确的演员阵容,你做出了signed int一个uint32_t不是本意的事情。
总的来说,您需要了解隐式类型提升规则。
虽然,在分配回 时存在隐式左值转换uint16_t,这在大多数情况下可以节省时间。
另请注意,这0x0000FFFF是危险的风格。十六进制文字是该值适合的类型,无论您在值之前放置了多少个零。在这种情况下,它int是签名的。在 16 位系统上,0x0000FFFF会给出int但0x00008000会给出unsigned int. (例如检查这个奇怪的错误:为什么 0 < -0x80000000?)
最佳实践、坚固、可移植、符合 MISRA-C 的代码是完全不包含任何隐式转换的代码:
uint32_t nbr = ...;
uint16_t lower_word = (uint16_t) (nbr & 0xFFFFUL);
uint16_t upper_word = (uint16_t) ((nbr >> 16) & 0xFFFFUL);
这个假设nbr已知是uint32_t,否则最好将该操作数强制转换为uint32_t强制转换之前。
在这种特定情况下,掩码并不是真正需要的,但在一般情况下,例如从 a 中屏蔽 4 个字节时uint32_t。