如何在 C 中打印无符号字符?

我试图将 char 打印为正值:

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

但我得到了:

4294967252

如何在输出中得到 212

304884 次浏览

声明你的 ch

unsigned char ch = 212 ;

你的指纹会有用的。

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

212 = 0xD4

当它是符号扩展时,FF被预先挂起到你的数字,所以它变成

0xFFFFFFD4 = 4294967252

就是打印出来的数字。

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

6.1.1.2: 如果一个 int可以表示原始类型的所有值,那么该值将被转换为 int; 否则,它将被转换为 unsigned int

这会导致将 int传递给格式说明符 %u,后者需要 unsigned int

为了避免在程序中出现未定义行为,添加如下显式的类型强制转换:

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


* 一般来说,该标准将 char的签名权留给实现。详情请参阅 这个问题

Char 的范围是127到 -128。如果分配212,则 ch 存储 -44(212-128-128)而不是212。所以如果你尝试打印一个无符号的负数,你会得到 (无符号整型的最大值)-abs (数字),在这个例子中是4294967252

所以如果你想像在 ch 中那样存储212,你唯一能做的就是声明 ch as

unsigned char ch;

现在 ch 的范围是0到255。

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

unsigned char ch = 212;

其次,在 printf("%u",ch)中,ch在普通 C 实现中将被提升为 int。但是,%u说明符需要 unsigned int,而 C 标准并不定义传递错误类型时的行为。相反,它应该是:

printf("%hhu", ch);

(对于 %hhuprintf期望 unsigned char在正常的 C 实现中被提升到 int。)

因为在默认情况下,char声明为 signed,这意味着变量的范围为

-127至 + 127 >

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

 0 to 255

为了得到任何数据类型的范围遵循以下过程 2^bit例子 char是8位长度得到它的范围只有 2 ^(power) 8

如因任何理由而不能更改声明,你可:

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