69

我正在尝试将 char 打印为正值:

char ch = 212;
printf("%u", ch);

但我得到:

4294967252

我怎样才能进入212输出?

4

6 回答 6

43

声明你ch

unsigned char ch = 212 ;

您的 printf 将起作用。

于 2013-04-01T01:35:55.387 回答
39

这是因为在这种情况下,该char类型已在您的系统上签名*。发生这种情况时,数据会在默认转换期间进行符号扩展,同时将数据传递给具有可变数量参数的函数。由于 212 大于 0x80,它被视为负数,%u将数字解释为一个大的正数:

212 = 0xD4

当它被符号扩展时,FFs 会在你的号码前附加,所以它变成

0xFFFFFFD4 = 4294967252

这是打印的数字。

请注意,此行为特定于您的实现。根据 C99 规范,所有char类型都提升为 (signed) int,因为 an可以表示 a 、有符号或无符号int的所有值:char

6.1.1.2:如果anint可以表示原始类型的所有值,则将该值转换为an int;否则,将其转换为unsigned int.

这导致将 a 传递int给格式说明符%u,该说明符需要unsigned int.

为避免程序中出现未定义的行为,请按如下方式添加显式类型转换:

unsigned char ch = (unsigned char)212;
printf("%u", (unsigned int)ch);


*通常,标准将签名留给char实施。有关更多详细信息,请参阅此问题

于 2013-04-01T01:36:30.797 回答
19

这段代码有两个错误。首先,在大多数带有 signed 的 C 实现中char,存在一个问题,char ch = 212因为 212 不适合 8 位 signed char,并且 C 标准没有完全定义行为(它需要实现来定义行为)。它应该是:

unsigned char ch = 212;

其次, in printf("%u",ch),ch将被提升为intin 正常的 C 实现。但是,说明%u符需要一个unsigned int,并且 C 标准没有定义传递错误类型时的行为。它应该是:

printf("%hhu", ch);

(对于%hhu,printf期望unsigned char在正常的 C 实现中已被提升为int。)

于 2013-04-01T13:57:22.513 回答
3

如果您因任何原因无法更改声明,您可以执行以下操作:

char ch = 212;
printf("%d", (unsigned char) ch);
于 2016-03-14T02:24:25.170 回答
1

char 的范围是 127 到 -128。如果您分配 212,则 ch 存储 -44 (212-128-128) 而不是 212。因此,如果您尝试将负数打印为无符号,则会得到(无符号整数的最大值)-abs(number),在这种情况下为 4294967252

因此,如果您想将 212 原样存储在 ch 中,您唯一能做的就是将 ch 声明为

unsigned char ch;

现在 ch 的范围是 0 到 255。

于 2013-04-01T01:50:08.990 回答
1

因为char是默认signed声明的,这意味着变量的范围是

-127 至 +127>

你的价值溢出了。要获得所需的值,您必须声明unsigned修饰符。修饰符的 ( unsigned) 范围是:

 0 to 255

要获取任何数据类型的范围,请按照流程2^bit示例char是 8 位长度来获取其范围2 ^(power) 8

于 2014-07-19T16:56:34.790 回答