int到char cast,奇怪的行为

int到char cast,奇怪的行为,c,char,printf,implicit-conversion,integer-promotion,C,Char,Printf,Implicit Conversion,Integer Promotion,考虑以下几点: unsigned int i1=0xFFFFFFFF; 无符号字符c1=i1; 字符c2=i1; printf(“%x\n”,i1);//0xFFFFFFFF与预期一致 printf(“%x\n”,c1);//0xFF如预期的那样 printf(“%x\n”,c2);//0xFFFFFFFF???? printf(“%d\n”,c1==c2);//假???? 我知道,不应该将int分配给char。无论如何,看看c2似乎存储了超过一个字节。我所期望的是将n1的“低有效字节”复制到

考虑以下几点:

unsigned int i1=0xFFFFFFFF;
无符号字符c1=i1;
字符c2=i1;
printf(“%x\n”,i1);//0xFFFFFFFF与预期一致
printf(“%x\n”,c1);//0xFF如预期的那样
printf(“%x\n”,c2);//0xFFFFFFFF????
printf(“%d\n”,c1==c2);//假????

我知道,不应该将
int
分配给
char
。无论如何,看看
c2
似乎存储了超过一个字节。我所期望的是将
n1
的“低有效字节”复制到
c2
。我这么想是不是错了?没有复印件吗?为什么
无符号字符
的行为不同于
字符


实际上,我在使用时在一个非常具体的情况下发现了这一点。它返回一个结构,其中包含存储ipv4地址(四个8位长的数字)的字段
char*h_addr
。我想将ip地址打印为数字,但结果异常大



我知道一种解决方法,即使用
i1&0xFF
进行掩蔽,但我想了解这个问题。

在您的系统中,类型
char
的行为与类型
签名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 );
}
还有,你好像打错了字,还写了

printf("%d\n", n3 == n2);
而不是

printf("%d\n", c1 == c2);

如果是这样,则由于整数提升,比较运算符的操作数再次隐式转换为类型
int
。由于操作数
c1
具有类型
无符号字符
,因此将其转换为值
0x000000FF
,而存储负值的操作数
c2
将转换为值
0xffffff
。因此结果值彼此不相等。

什么是n1、n2和n3?我看到了i1(不是n1)。当传递到
printf
char
时,将转换为
int
。您学会了在混合有符号和无符号值时非常非常小心。我怀疑如果你启用了所有的编译器警告,你会得到大量的警告。“我知道,一个人不应该给一个字符分配一个int”-还有更多的东西需要忘记。你总是这么做time@AnttiHaapala:这里的措词不清楚。将
int
类型分配给
char
本身是可以的,但如果
int
值可能超出
char
中可表示的值,则通常不可以将
int
值分配给
char
,因为它是不可移植的(未完全由C标准定义,不产生严格符合标准的代码,并且可能存在陷阱)。
printf("%d\n", c1 == c2);