问题描述
正如标题所示,运行以下代码时出现怪异结果:
#include $ b int main()
{
char buff [4] = {0x17,0x89,0x39,0x40};
unsigned int * ptr =(unsigned int *)buff; (3 * 8));
char a =(char)((* ptr <>(3 * 8));
printf(0x%x \ n,* ptr);
printf(0x%x \,a);
printf(0x%x \ n,b);
printf(0x%x \,c);
printf(0x%x \ n,d);
返回0;
}
输出:
0x40398917
0x40
0x39
0xffffff89
0x17
为什么我没有得到 0x89
?
char
变量是被签名的,并且它们在被升级(在这种情况下被升级到更宽的类型)时正在进行符号扩展。签名扩展是在进行此促销时保留标志的一种方式,因此 -119
保持为 -119
,无论它是8位,16位或更宽的类型。您可以通过明确使用 unsigned char
来修复它,因为,至少在C中, char
是有符号还是无符号是特定于实现的。从 C11 6.2.5类型/ 15
:
签名扩展名无法用于无符号类型因为他们,...好,没有签名: - )
As the title says, I get a "weird" result when running the following code:
#include <stdio.h>
int main()
{
char buff[4] = {0x17, 0x89, 0x39, 0x40};
unsigned int* ptr = (unsigned int*)buff;
char a = (char)((*ptr << (0*8)) >> (3*8));
char b = (char)((*ptr << (1*8)) >> (3*8));
char c = (char)((*ptr << (2*8)) >> (3*8));
char d = (char)((*ptr << (3*8)) >> (3*8));
printf("0x%x\n", *ptr);
printf("0x%x\n", a);
printf("0x%x\n", b);
printf("0x%x\n", c);
printf("0x%x\n", d);
return 0;
}
Output:
0x40398917
0x40
0x39
0xffffff89
0x17
Why am I not getting 0x89
?
It's because your char
variables are signed and they're undergoing sign extension when being promoted (upgraded to a wider type in this case). Sign extension is a way of preserving the sign when doing this promotion, so that -119
stays as -119
whether it's 8-bit, 16-bit or a wider type.
You can fix it by explicitly using unsigned char
since, in C at least, whether char
is signed or unsigned is implementation-specific. From C11 6.2.5 Types /15
:
Sign extension does not come into play for unsigned types because they're, ... well, unsigned :-)
这篇关于打印值0x89(-119)时发生奇怪的输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!