【问题标题】:int to char cast, strange behaviorint 到 char 转换,奇怪的行为
【发布时间】:2021-05-03 17:24:32
【问题描述】:

考虑以下几点:

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() 时在一个非常具体的情况下发现的。它返回一个结构,其中包含一个字段char *h_addr,该字段存储一个 ipv4 地址(四个 8 位长的数字)。我想将 IP 地址打印为数字,但结果异常大。


我知道一种解决方法,使用 i1 & 0xFF 进行屏蔽可以工作,但我想了解这个问题。

【问题讨论】:

  • 什么是 n1、n2 和 n3?我看到 i1(不是 n1)。
  • 当传递给printf 时,char 正在转换为int
  • 你学会了在混合有符号和无符号值时非常非常小心。我怀疑如果你启用所有编译器警告,你会得到很多。
  • “我知道,不应该将 int 分配给 char”——还有更多需要学习的东西。你一直这样做
  • @AnttiHaapala:这里的措辞不清楚。 本身可以将int 类型分配给char,但如果int 值可能在值之外,则通常不可以将int 值分配给char可在 char 中表示,因为它不可移植(未完全由 C 标准定义,不会产生严格符合的代码,并且可能会陷入陷阱)。

标签: c char printf implicit-conversion integer-promotion


【解决方案1】:

在您的系统中,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 因为它存储负值被转换为值0xFFFFFFFF。所以结果值不相等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    • 2017-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多