如何在C中打印unsigned char?

Ant*_*ton 53 c printf

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

char ch = 212;
printf("%u", ch);
Run Code Online (Sandbox Code Playgroud)

但我得到:

4294967252
Run Code Online (Sandbox Code Playgroud)

我如何212进入输出?

小智 36

声明你ch

unsigned char ch = 212 ;
Run Code Online (Sandbox Code Playgroud)

而你的printf将起作用.

  • 即使将`ch`更改为`unsigned char`,代码的行为也不是由C标准定义的.这是因为`unsigned char`被提升为`int`(在普通的C实现中),所以`int`被传递给`printf`用于说明符'%u`.但是,`%u`需要`unsigned int`,因此类型不匹配,C标准没有定义行为. (13认同)
  • 你的评论不正确.C11标准规定转换说明符必须与函数`argument`本身的类型相同,而不是提升类型.这一点也在`hh` length修饰符的描述中得到了具体解决:"参数将根据整数提升进行提升,但其值应在打印前转换为signed char或unsigned char" (4认同)
  • @ andrew.punnett:函数参数是提升的值;它具有根据C 2011 6.5.2.2整数促销得出的类型。6.对于“ hh”,是的,该标准告诉我们促销之前的类型可以是“有符号字符”或“无符号字符”。 。这意味着`ch`仍将被提升为`int`,但是转换`%hhu`期望如此。但是,这与在“ printf(%u,ch)”中不存在“ hh”的情况无关。 (2认同)

das*_*ght 31

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

212 = 0xD4
Run Code Online (Sandbox Code Playgroud)

当它被符号扩展时,FFs被预先设置为你的号码,所以它变成了

0xFFFFFFD4 = 4294967252
Run Code Online (Sandbox Code Playgroud)

这是打印的数字.

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

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

这导致传递int给格式说明符%u,期望一个unsigned int.

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

unsigned char ch = (unsigned char)212;
printf("%u", (unsigned int)ch);
Run Code Online (Sandbox Code Playgroud)


*一般而言,该标准留下char了实施的签名.有关详细信息,请参阅此问题.


Eri*_*hil 11

这段代码中有两个错误.首先,在大多数带有signed的C实现中char,存在溢出,char ch = 212因为212不适合8位有符号char,并且C标准在存在整数溢出时不定义行为.它应该是:

unsigned char ch = 212;
Run Code Online (Sandbox Code Playgroud)

其次,在printf("%u",ch),ch将被提升到一个int正常C实现.但是,说明%u符需要a unsigned int,而C标准在传递错误类型时不会定义行为.它应该是:

printf("%u", (unsigned) ch);
Run Code Online (Sandbox Code Playgroud)

  • @ShitalShah:这个问题用C标记,而不是C ++。C没有static_cast运算符。 (2认同)