C语言 int转换成字符转换,奇怪的行为



考虑以下内容:

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 charchar的行为不同?


我实际上在使用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。因此结果值彼此不相等。

最新更新