我试图将 char 打印为正值:
char ch = 212; printf("%u", ch);
但我得到了:
4294967252
如何在输出中得到 212?
212
声明你的 ch为
ch
unsigned char ch = 212 ;
你的指纹会有用的。
这是因为在这种情况下,char类型是在 system*上签名的。当这种情况发生时,数据在默认转换期间得到符号扩展,同时将数据传递给具有可变参数数量的函数。因为212大于0x80,它被视为负数,%u将这个数字解释为一个大的正数:
char
%u
212 = 0xD4
当它是符号扩展时,FF被预先挂起到你的数字,所以它变成
FF
0xFFFFFFD4 = 4294967252
就是打印出来的数字。
请注意,此行为是特定于您的实现的。根据 C99规范,所有 char类型都被提升为(有符号的) int,因为 int可以表示 char的所有值,无论是有符号的还是无符号的:
int
6.1.1.2: 如果一个 int可以表示原始类型的所有值,那么该值将被转换为 int; 否则,它将被转换为 unsigned int。
unsigned int
这会导致将 int传递给格式说明符 %u,后者需要 unsigned int。
为了避免在程序中出现未定义行为,添加如下显式的类型强制转换:
unsigned char ch = (unsigned char)212; printf("%u", (unsigned int)ch);
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 标准没有完全定义行为(它需要实现来定义行为)。相反,它应该是:
char ch = 212
unsigned char ch = 212;
其次,在 printf("%u",ch)中,ch在普通 C 实现中将被提升为 int。但是,%u说明符需要 unsigned int,而 C 标准并不定义传递错误类型时的行为。相反,它应该是:
printf("%u",ch)
printf("%hhu", ch);
(对于 %hhu,printf期望 unsigned char在正常的 C 实现中被提升到 int。)
%hhu
printf
unsigned char
因为在默认情况下,char声明为 signed,这意味着变量的范围为
signed
-127至 + 127 >
你的价值已经溢出来了。要获得所需的值,必须声明 unsigned修饰符。修饰词(unsigned)的范围是:
unsigned
0 to 255
为了得到任何数据类型的范围遵循以下过程 2^bit例子 char是8位长度得到它的范围只有 2 ^(power) 8。
2^bit
2 ^(power) 8
如因任何理由而不能更改声明,你可:
char ch = 212; printf("%d", (unsigned char) ch);