Abd*_*eem 4 c cpu-word uint32 uint16
要提取无符号32位整数的高位字和低位字,并将每个字存储在单独的uint16_t变量中,我执行如下操作(nbr是无符号的32位整数):
uint16_t lower_word = (uint16_t) nbr & 0x0000FFFF; // mask desired word
uint16_t upper_word = (uint16_t) ((nbr & 0xFFFF0000) >> 16); // right-shift after masking
Run Code Online (Sandbox Code Playgroud)
显式转换为uint16_t是不必要的吗?还有什么其他更有效的方法,如果有的话,你建议获得所需的结果而不是这种方法吗?
uint16_t lower_word = (uint16_t) nbr;
uint16_t upper_word = (uint16_t) (nbr >> 16);
Run Code Online (Sandbox Code Playgroud)
面具没用
cast是必要的,否则编译器可能会产生警告
{编辑以考虑Lundin/Eric Postpischil的评论}
例如,gcc -Wconversion在没有演员的情况下发出警告
C型系统既微妙又危险.显式转换可能是必要的,也可能不是必需的.在(uint16_t) nbr & 0x0000FFFF具体情况下,假设32位CPU,演员表是不正确的.
你在行动发生前施放.意味着操作数nbr将由强制转换显式转换,然后int通过隐式整数提升立即隐式转换为.结果将是类型int,已签名.在这种情况下无害但在其他情况下会引起麻烦.通过使用不正确的演员,你做了signed int一个uint32_t不是意图.
总的来说,您需要了解隐式类型促销规则.
虽然,在分配时会有一个隐含的左值转换uint16_t,大部分时间都会节省一天.
还要注意那0x0000FFFF是危险的风格.无论您在值之前放置多少个零,Hex文字都是值适合的类型.在这种情况下,它int是签署的.在一个16位系统上,0x0000FFFF会给,int但0x00008000会给unsigned int.(例如,检查这个奇怪的bug:为什么0 <-0x80000000?)
最佳实践,坚固耐用,可移植,符合MISRA-C的代码,是完全不包含任何隐式转换的代码:
uint32_t nbr = ...;
uint16_t lower_word = (uint16_t) (nbr & 0xFFFFUL);
uint16_t upper_word = (uint16_t) ((nbr >> 16) & 0xFFFFUL);
Run Code Online (Sandbox Code Playgroud)
这个假设nbr是已知的uint32_t,否则最好将该操作数uint32_t转换为强制转换.
在这种特定情况下,掩码并不是必需的,但在一般情况下,例如从a屏蔽掉4个字节时uint32_t.