我正在尝试将char打印为正值:
char ch = 212;
printf("%u", ch);
但我明白了:
4294967252
如何在输出中获得212
?
答案 0 :(得分:34)
将您的ch
声明为
unsigned char ch = 212 ;
你的printf会起作用。
答案 1 :(得分:30)
这是因为在这种情况下,char
类型在您的系统 * 上签名。发生这种情况时,数据在默认转换期间进行符号扩展,同时将数据传递给具有可变数量参数的函数。由于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
的签名留给实现。有关详细信息,请参阅this question。
答案 2 :(得分:10)
此代码中有两个错误。首先,在大多数带有签名char
的C实现中,char ch = 212
中存在溢出,因为212不适合8位带符号char
,并且C标准不定义行为时有整数溢出。它应该是:
unsigned char ch = 212;
其次,在printf("%u",ch)
中,ch
将在正常的C实现中升级为int
。但是,%u
说明符需要unsigned int
,并且C标准在传递错误类型时不会定义行为。它应该是:
printf("%u", (unsigned) ch);
答案 3 :(得分:1)
char的范围是127到-128。如果您指定212,ch存储-44(212-128-128)而不是212.So如果您尝试将负数打印为无符号,则得(无符号整数的最大值)-abs(数字)在这种情况下是4294967252
因此,如果您想要存储212,因为它只能将ch声明为
unsigned char ch;
现在ch的范围是0到255。
答案 4 :(得分:1)
因为char
默认为signed
声明,这意味着变量的范围是
-127至+ 127&gt;
你的价值已经溢出。要获得所需的值,您必须声明unsigned
修饰符。修饰符(unsigned
)范围是:
0 to 255
要获取任何数据类型的范围,请遵循流程2^bit
示例char
为8位长度,以使其范围仅为2 ^(power) 8
。
答案 5 :(得分:1)
如果您因任何原因无法更改声明,您可以执行以下操作:
char ch = 212;
printf("%d", (unsigned char) ch);