unsigned char的格式说明符

12 c

说我要打印unsigned char:

unsigned char x = 12;
Run Code Online (Sandbox Code Playgroud)

哪个是对的.这个:

printf("%d",x);
Run Code Online (Sandbox Code Playgroud)

或这个:

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

事情就在其他地方我遇到过这样的讨论:

- 即使ch更改为unsigned char,代码的行为也不是由C标准定义的.这是因为unsigned char被提升为int(在普通的C实现中),因此将int传递给printf以获取指定符%u.但是,%u期望unsigned int,因此类型不匹配,并且C标准不定义行为

- 你的评论不正确.C11标准规定转换说明符必须与函数参数本身的类型相同,而不是提升类型.hh length修饰符的描述中也明确说明了这一点:"参数将根据整数提升进行提升,但其值应在打印前转换为signed char或unsigned char"

哪个是正确的?任何可靠的消息来源都说这个问题?(从这个意义上说,我们也应该unsigned short用%d 打印int,因为它可以被提升为int?).

Grz*_*ski 8

正确的是*:

printf("%d",x);
Run Code Online (Sandbox Code Playgroud)

这是因为默认参数促销printf()可变参数函数一样.这意味着unsigned char值始终被提升为int.

从N1570(C11草案)6.5.2.2/6 函数调用(强调我的前进):

如果表示被调用函数的表达式具有不包含原型的类型,则对每个参数执行整数提升,并将具有类型的参数float提升为 double.这些被称为默认参数促销.

6.5.2.2/7子条款告诉:

函数原型声明符中的省略号表示法导致参数类型转换在最后声明的参数之后停止.该参数默认晋级是在尾随参数执行.

这些整数提升以6.3.1.1/2 布尔值,字符和整数定义:

如果a int 可以表示原始类型的所有值(由宽度限制,对于位字段),则该值将转换为int; 否则,它被转换为unsigned int.这些被称为 整数促销.58)所有其他类型由整数促销不变.

这句话回答了你的第二个问题unsigned short(见下面的评论).


*除了超过8位unsigned char(例如它可能占用16位),请参阅@ chux的答案.


chu*_*ica 8

正确的格式说明符unsigned char x = 12取决于许多事情:

如果INT_MAX >= UCHAR_MAX经常出现这种情况,请使用"%d".在这种情况下,unsigned char升级为int.

printf("%d",x);
Run Code Online (Sandbox Code Playgroud)

否则使用"%u"(或"%x","%o").在这种情况下,unsigned char升级为unsigned.

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

最新的编译器支持"hh"长度修改器,可以弥补这种不确定性.应该x升级到intunsigned由于可变参数的标准促销,printf()将其转换为unsigned char打印前.

printf("%hhu",x);
Run Code Online (Sandbox Code Playgroud)

如果在没有"hh"或寻求高度可移植代码的情况下处理旧编译器,请使用显式转换

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

相同的问题/答案适用于unsigned short,期望INT_MAX >= USHRT_MAX和使用"h"而不是"hh".