简体   繁体   English

为什么在printf中指定为整数的char被正确打印

[英]Why char specified as integer in printf gets printed correctly

Why does the following code work? 为什么以下代码有效?

char c = 'A';
printf("%d - size: %d", c, sizeof(c));

Prints out: 打印出来:

65 - size: 1

Why is the output not garbage, since an int would usually be 4 bytes long and we can clearly see that the char is 1 byte long. 为什么输出不是垃圾,因为int通常是4个字节长,我们可以清楚地看到char是1个字节长。 Does the compiler do the implicit conversation? 编译器是否进行隐式对话?

Any integer type with a rank lower than int is promoted to either int or unsigned int anytime it is used in an expression. 任何低于int整数类型都会在表达式中使用时提升intunsigned int This is specified in section 6.3.1.1p2 of the C standard: 这在C标准的6.3.1.1p2节中规定:

The following may be used in an expression wherever an int or unsigned int may be used: 如果可以使用int或unsigned int,则可以在表达式中使用以下内容:

  • An object or expression with an integer type (other than int or unsigned int ) whose integer conversion rank is less than or equal to the rank of int and unsigned int . 具有整数类型(int或unsigned int除外)的对象或表达式,其整数转换等级小于或等于int和unsigned int的等级。
  • A bit-field of type _Bool , int , signed int ,or unsigned int . _Bool,int,signed int或unsigned int类型的位字段。

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 ; 如果int可以表示原始类型的所有值(由宽度限制,对于位字段),则该值将转换为int; otherwise, it is converted to an unsigned int . 否则,它将转换为unsigned int。 These are called the integer promotions . 这些被称为整数促销。

All other types are unchanged by the integer promotions 整数促销不会更改所有其他类型

That's what is happening in this case, since the printf function doesn't implicitly know the type of its parameters at compile time. 这就是在这种情况下发生的事情,因为printf函数在编译时不会隐式地知道其参数的类型。 So the char argument is promoted to int , and using %d to format it is valid. 所以char参数被提升为int ,并使用%d来格式化它是有效的。

There is a special rule for functions with variable-length argument lists, like printf . 对于具有可变长度参数列表的函数,有一个特殊规则,如printf In the variable-length portion of the argument list, all integral arguments smaller than int are promoted to int , and float is promoted to double . 在参数列表的可变长度部分中,小于int所有整数参数都被提升为int ,而float被提升为double So it turns out it's perfectly fine to print a character (or a short ) using %d . 所以事实证明使用%d打印字符(或short )是完全没问题的。

These default argument promotions end up accounting for a number of anomalies in printf . 这些默认参数促销最终会导致printf的许多异常。 You might think that the correct format specifiers for char , short , int , float , and double are %hhd , %hd , %d , %f , and %lf , respectively. 您可能认为charshortintfloatdouble的正确格式说明符分别是%hhd%hd%d%f%lf But in fact you can get away with %d , %d , %d , %f , and %f . 但实际上你可以逃脱%d%d%d%f%f printf basically ignores the l modifier for floating point, and it seems to ignore the h modifier for integers. printf基本上忽略了浮点数的l修饰符,它似乎忽略了整数的h修饰符。 (Actually h can make a difference in obscure cases, as chux explains in a comment.) (实际上, h可以在不明显的案例中发挥作用,正如chux在评论中解释的那样。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM