8位灰度值转32位RGBA颜色值时代码输出不符合预期问题求助
问题1:第一段代码输出fefeffee的原因
- 多数C编译器默认
char为有符号字符类型,0xEE二进制最高位为1,实际表示的是负数,值为-18。 - 将有符号char强转为int时会触发符号扩展:高位全部补1,因此
(int)c的实际值是0xFFFFFFEE,不是你预期的0x000000EE。 - 运算
0xFF000000 + 0xFFFFFFEE时,32位int会截断溢出的高位,最终得到结果0xFEFFFFEE。
问题2:移位表达式输出0的原因
C语言中加法运算符优先级高于移位运算符,你写的表达式:
(int)(0xFF << 24 + c << 16 + c << 8 + c);
实际会先计算所有加法项,等价于:
(int)(0xFF << (24 + c) << (16 + c) << (8 + c));
c的值为0xEE即十进制238,24 + c = 262,远超过32位int的有效移位位数(0~31),这类超出位数的移位属于未定义行为,多数编译器会将移位位数对32取模,最终移位结果直接为0,后续移位操作也不会改变结果。
修改后代码正常运行的原因
- 将
c声明为unsigned char,无符号字符转为整数时不会触发符号扩展,(unsigned int)c的值就是预期的0x000000EE。 - 拆分移位和加法操作,避免了运算符优先级导致的逻辑错误。
- 使用
unsigned int存储颜色值,避免了有符号整数移位、运算溢出的未定义行为。
内容的提问来源于stack exchange,提问作者mareque
相关产品推荐
相关产品推荐

