在为uni写程序的时候,我注意到
unsigned char byte_to_write_1 = (0xFF << 2) >> 2; ==> 0xFF (wrong)
unsigned char byte_to_write_2 = (0xFF << 2);
byte_to_write_2 = byte_to_write_2 >> 2; ==> 0x3F (correct)
我不明白是什么导致了这种差异......我最好的猜测是,当在同一行上用多个操作修改一个字节时,C会“保留”稍大的数据类型中的额外位,直到该行终止,因此0xFF〈〈2被保留为11[1111 1100],而不是1111 1100,因此在同一行上的回移,结果是1111111而不是11111100。
是什么导致结果的差异?提前感谢...
我第一次注意到这个问题是在一个更大的代码项目中,但我已经能够使用一个简单得多的程序重现这个问题。image of simplified code to showcase problem
2条答案
按热度按时间px9o7tmv1#
0xFF
是一个int
。(从unsigned char
获得0xFF
不会改变任何东西,因为它将被提升为int
。)0xFF << 2
是0x3FC
。0x3FC >> 2
是0xFF
。我们已经确定了
0xFF << 2
是0x3FC
,但是你把它赋给了一个unsigned char
,而这个unsigned char
大概只有8位大小,所以你最后把它赋给了0xFC
(如果你启用了警告功能,gcc
会发出警告)。当然,当你把它右移的时候,你会得到想要的值。
解决方案:
一个一个二个一个一个一个三个一个一个一个一个一个四个一个
Demo(位于编译器资源管理器上)。
jgovgodb2#
这两个代码段之间的区别
以及
在第二段代码中,使用变量
byte_to_write_2
来存储表达式(0xFF << 2)
的中间结果,该变量不能保存完整的整数结果,因此将整数结果转换为只能存储一个字节的类型unsigned char
。unsigned character
类型的对象中可存储的最大值为0xFF
而等价于
255 * 4
的表达式0xFF << 2
不能适合类型为unsigned char
的对象。在第一个代码片段中,由于整数提升,表达式
(0xFF << 2)
的中间结果具有类型int
,并且可以在不更改完整表达式(0xFF << 2) >> 2
的情况下使用。考虑
printf
的这两个调用的输出他们是