unsigned char x = 12;
哪个是对的.这个:
printf("%d",x);
或这个:
printf("%u",x);
?
事情在其他地方,我遇到这样的讨论:
– 即使ch更改为unsigned char,代码的行为也不是由C标准定义的.这是因为unsigned char被提升为一个int(在正常的C实现中),所以int被传递给printf用于说明符%u.但是,%u希望有一个unsigned int,所以类型不匹配,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功能调用(重点是我的未来):
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 typefloat
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中定义为布尔值,字符和整数:
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 anint
;
otherwise,it is converted to anunsigned int
. These are called the
integer promotions.58) All other types are unchanged by the integer
promotions.
这个报价回答了你的第二个无符号短信问题(见下面的评论).
*除了超过8位的unsigned char(例如它可能占用16位),请参见@ chux的answer.