int to char cast,奇怪的行为

问题描述

考虑以下事项:

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} }}。所以结果值彼此不相等。