c - 无符号字符的格式说明符

标签 c

假设我想打印unsigned char:

unsigned char x = 12;

这是正确的。这:

printf("%d",x);

或者这个:

printf("%u",x);

?

事情在别处所以我遇到这样的讨论:

-即使将 ch 更改为 unsigned char,代码的行为也未由 C 标准定义。这是因为 unsigned char 被提升为一个 int(在正常的 C 实现中),因此一个 int 被传递给 printf 作为说明符 %u。但是,%u 需要一个无符号整数,因此类型不匹配,并且 C 标准没有定义行为

-您的评论不正确。 C11 标准规定转换说明符必须与函数参数本身属于同一类型,而不是提升后的类型。这一点在 hh 长度修饰符的描述中也有具体说明:“参数将根据整数提升进行提升,但其值在打印前应转换为 signed char 或 unsigned char”

那么哪个是正确的呢?有可靠的消息来源说这件事吗? (从这个意义上说,我们还应该用 %d 打印 unsigned short int,因为它可以提升为 int?)。

最佳答案

正确的是*:

printf("%d",x);

这是因为 默认参数提升 因为 printf() 是可变参数函数。这意味着 unsigned char 值总是被提升为 int

来自 N1570(C11 草案)6.5.2.2/6 函数调用(强调我的 future ):

If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions.

6.5.2.2/7子条款告诉:

The ellipsis notation in a function prototype declarator causes argument type conversion to stop after the last declared parameter. The default argument promotions are performed on trailing arguments.

这些整数提升在 6.3.1.1/2 中定义 bool 值、字符和整数:

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.58) All other types are unchanged by the integer promotions.

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


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

关于c - 无符号字符的格式说明符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27547377/

相关文章:

无法分配请求的地址 - 可能的原因?

在 (f)lex 中复制整个输入行(以获得更好的错误消息)?

c - 我在 C 代码 : invalid operands to binary expression ('long long (int)' and 'int' ) and I don't know how to fix 中收到错误

C 数组算法中的最大数

c - 在 C 中声明二维数组只知道一个的长度

c - 使用 inet_pton 将计算出的网络地址存储在 '' struct in6_addr '' or "struct in6_addr.sin6_addr"

C 初始化矩阵

c - 如何发现文件夹中存在哪些文件

c - 访问二维数组一行末尾的元素是 UB 吗?

c - 如何保护Linux中进程间共享的内存