简体   繁体   English

在整数和浮点数上打印运算结果

[英]Printing the result of operations on integers and floats

Consider the following C-program: 考虑以下C程序:

int main() {
    int a =2;
    float b = 2;
    float c = 3;
    int d = 3;
    printf("%d %f %d %f %d %f %d %f\n", a/c, a/c, a/d, a/d, b/c, b/c, b/d, b/d);
    printf("%d\n", a/c);
}

The output of this is: 输出为:

 0 0.666667 0 0.666667 2 0.666667 0 0.666667
 539648

I can't make sense of this at all. 我完全无法理解这一点。 Why does printing a/c as an integer give 0, while b/c gives 2? 为什么将a / c打印为整数给出0,而将b / c打印给出2? Aren't all integers promoted to floats in computations involving both floats and integers? 在涉及浮点数和整数的计算中,不是所有整数都提升为浮点数吗? So the answer should be 0 in both cases. 因此,在两种情况下答案都应为0。

In the second line of the output I'm simply printing a/c as an integer, which gives a garbage value for some reason (even though it gives 0 when I print it in the first compound printf statement). 在输出的第二行中,我只是将a / c打印为整数,由于某种原因,它给出了垃圾值(即使当我在第一个复合printf语句中将其打印为0时,它也会给出垃圾值)。 Why is this happening? 为什么会这样呢?

You have undefined behaviour: 您有未定义的行为:

printf("%d %f %d %f %d %f %d %f\n", a/c, a/c, a/d, a/d, b/c, b/c, b/d, b/d);

The format specifier for printf must match the type of the provided parameter. printf的格式说明符必须与所提供参数的类型匹配。 As printf doesn't provide a parameter list with types, but only ... there is no implicit type conversion apart from standard type conversion. 由于printf不提供带有类型的参数列表,而仅提供...除了标准类型转换外,没有隐式类型转换。

If you have UB, basically anything can happen. 如果您有UB,基本上任何事情都可能发生。

What is likely to happen is the following: 可能发生的情况如下:

Depending on the format specifier, printf consumes a certain number of bytes from the calling parameters. 根据格式说明符, printf从调用参数中消耗一定数量的字节。 This number of bytes matches the specified format type. 此字节数与指定的格式类型匹配。 If the number of bytes does not match the number of bytes passed as an argument, you are out of sync for all successive parameters. 如果字节数与作为参数传递的字节数不匹配,则所有后续参数都不同步。 And of course you do incorrect interpretation of the data. 当然,您对数据进行了错误的解释。

For starters according to the C Standard the function main without parameters shall be declared like 对于符合C标准的启动器,应声明无参数的main函数,例如

int main( void )

If you have for example the following declarations 例如,如果您有以下声明

int a =2;
float c = 3;

and then call the function printf the following way 然后通过以下方式调用函数printf

printf( "%d", a / c );

then behind the hood the following events occur. 然后幕后发生了以下事件。

The expression a / c has the type float due to the usual arithmetic conversions . 由于通常的算术转换 ,表达式a / c具有float类型。

As the function printf is declared with the ellipsis notation then to the expression a / c of the type float there are applied the default argument promotions that convert the expression to the type double . 当函数printf用省略号表示时,然后对float类型的a / c表达式应用默认的参数提升 ,将表达式转换为double类型。

As result in this call there is an attempt to output an expression of the type double using conversion specifier %d designed for the type int . 作为该调用的结果,尝试使用为int类型设计的转换说明符%d输出double类型的表达式。 Hanse the call has undefined behavior. Hanse呼叫具有未定义的行为。

From the C Standard (7.21.6.1 The fprintf function) 根据C标准(7.21.6.1 fprintf函数)

9 If a conversion specification is invalid, the behavior is undefined.275) If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined. 9如果转换规范无效,则行为未定义。275) 如果任何参数不是对应转换规范的正确类型,则行为未定义。

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

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