为什么printf的hh和h长度修饰符存在?
在可变参数函数中,会发生默认参数提升。
6.5.2.2.6 如果表示被调用函数的表达式的类型不包含原型,则对每个参数执行整数提升,并将具有类型的参数
float提升为double。这些称为默认参数提升。[...]
6.5.2.2.7 [...] 函数原型声明符中的省略号会导致参数类型转换在最后一个声明的参数之后停止。默认参数提升是在尾随参数上执行的。
所以,
signed char c = 123;
int i = 123;
float f = 123;
double d = 123;
printf("%dn", i); // ok
printf("%dn", c); // ok, even though %d expects int.
printf("%fn", d); // ok
printf("%fn", f); // ok, even though %f expects double.
那么为什么( ) 和( )有一个printf长度修饰符呢?charhhshorth
章节编号参见 N2176。
回答
考虑这个例子:
#include <stdio.h>
int main(void)
{
unsigned short x = 32770;
printf("%dn", x) ; // (1)
printf("%un", x) ; // (2)
}
在典型的 16 位实现中,默认参数提升unsigned short为unsigned int,而在典型的 32 位实现中,unsigned short变为int。
所以在 16 位系统上 (1) 是 UB 并且 (2) 是正确的,但是在 32 位系统上,(1) 是正确的和 (2) 可以争论是正确还是 UB。
使用%hu打印x在所有系统上工作的,你不必考虑这些问题。
可以为char具有sizeof(int) == 1.