考虑以下内容:
unsigned int i1 = 0xFFFFFFFF;
unsigned char c1 = i1;
char c2 = i1;
printf("%xn", i1); // 0xFFFFFFFF as expected
printf("%xn", c1); // 0xFF as expected
printf("%xn", c2); // 0xFFFFFFFF ????
printf("%dn", c1 == c2); // false ????
我知道,不应该把一个int
分配给一个char
。无论如何,看看c2
似乎存储超过一个字节。我所期望的是一个"不太重要的字节"的副本。将n1
转化为c2
。我的假设错了吗?难道根本就没有副本吗?为什么unsigned char
和char
的行为不同?
我实际上在使用gethostbyname()时在一个非常具体的情况下发现了这一点。它返回一个结构体,其中包含一个字段char *h_addr
,存储ipv4地址(四个8位长数字)。我想把ip地址打印成数字,但得到了异常大的结果。
我知道一个解决方案,用i1 & 0xFF
屏蔽工作,但我想了解这个问题。
在您的系统中,类型char
表现为类型signed char
。
赋值后
char c2 = n1;
注:这里似乎有一个错别字,你的意思是
char c2 = i1;
变量c2的值为0xff
,即-1
。
printf("%xn", c2);
参数表达式c2
由于整数提升被转换为传播符号位的int
类型。该值按照%x
的格式输出。
注意你需要写
printf( "%xn",( 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( "%xn", i1 );
printf( "%hhxn", c1 );
printf( "%hhxn", c2 );
}
程序输出为
ffffffff
ff
ff
还有,你好像打错了,把
printf("%dn", n3 == n2);
不是
printf("%dn", c1 == c2);
如果是,则由于整数提升,比较操作符的操作数再次隐式转换为int
类型。由于操作数c1
的类型为unsigned char
,因此将其转换为值0x000000FF
,而操作数c2
由于存储的是负值,因此将其转换为值0xFFFFFFFF
。因此结果值彼此不相等。