问题描述
考虑以下事项:
unsigned int i1 = 0xFFFFFFFF;
unsigned char c1 = i1;
char c2 = i1;
printf("%x\n",i1); // 0xFFFFFFFF as expected
printf("%x\n",c1); // 0xFF as expected
printf("%x\n",c2); // 0xFFFFFFFF ????
printf("%d\n",c1 == c2); // false ????
我知道,不应将 int
分配给 char
。无论如何,看看 c2
似乎存储的不仅仅是一个字节。我期望的是将 n1
的“不太重要的字节”复制到 c2
中。我错了吗?根本就没有副本吗?为什么 unsigned char
的行为与 char
不同?
实际上,我在使用 gethostbyname() 时在一个非常具体的情况下发现了这一点。它返回一个结构体,其中包含一个存储 ipv4 地址(四个 8 位长的数字)的字段 char *h_addr
。我想将 IP 地址打印为数字,但结果异常大。
我知道一种解决方法,使用 i1 & 0xFF
进行屏蔽是有效的,但我想了解这个问题。
解决方法
在您的系统中,类型 char
的行为与类型 signed char
相同。
本次任务结束后
char c2 = n1;
注意:似乎有一个错字,你的意思是
char c2 = i1;
变量 c2 的值为 0xff
,即 -1
。
在这次通话中
printf("%x\n",c2);
由于整数提升,参数表达式 c2
被转换为类型 int
传播符号位。并且这个值按照格式%x
输出。
注意你需要写
printf( "%x\n",( unsigned int ) c2 );
因为转换说明符 x
需要类型为 unsigned int
的对象。
如果您想获得预期的结果,您需要使用转换修饰符 hh
将对象输出为字符类型的对象。例如
#include <stdio.h>
int main(void)
{
unsigned int i1 = 0xFFFFFFFF;
unsigned char c1 = n1;
char c2 = n1;
printf( "%x\n",i1 );
printf( "%hhx\n",c1 );
printf( "%hhx\n",c2 );
}
程序输出为
ffffffff
ff
ff
而且你好像打错字了
printf("%d\n",n3 == n2);
代替
printf("%d\n",c1 == c2);
如果是这样,那么由于整数提升,比较运算符的操作数再次隐式转换为类型 int
。由于操作数 c1
的类型为 unsigned char
,因此它被转换为值 0x000000FF
,而操作数 c2
因为它存储负值被转换为值 {{1} }}。所以结果值彼此不相等。