简体   繁体   中英

Printing the result of operations on integers and floats

Consider the following C-program:

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? Aren't all integers promoted to floats in computations involving both floats and integers? So the answer should be 0 in both cases.

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). 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. As printf doesn't provide a parameter list with types, but only ... there is no implicit type conversion apart from standard type conversion.

If you have UB, basically anything can happen.

What is likely to happen is the following:

Depending on the format specifier, printf consumes a certain number of bytes from the calling parameters. 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

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( "%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 .

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 .

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 . Hanse the call has undefined behavior.

From the C Standard (7.21.6.1 The fprintf function)

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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