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
。