Data Type Confusion in C

The following code works:

int main(void) { float f = get_float(); int i = round(f*100); printf("%i\n", i); } 

However, an encoding error is generated as follows:

 printf("%i\n", round(1.21*100)); 

Output: round(1.21*100) - float . So then why

 int i = round(f*100); 

OK?

+5
source share
3 answers

When you do

 int i = round(f*100); 

you convert the result of the double round function. The converted result is stored in the variable int i , which can be used with the format "%i" because it expects an int argument.

When you pass the double result of round directly as an argument to the format that int expects, you have inappropriate formats and argument types. This leads to undefined behavior.

No conversion is performed in the printf call, and no conversion can be performed because the code inside the printf function does not know the actual type of the argument. All he knows is the format "%i" . All possible type information is lost for functions with a variable argument.

+15
source

This is due to the behavior of automatic casting. In printf, automatic casting does not work. When you say% i, it just expects an integer, it cannot convert double to integer and then print.

In an assignment operation, double is first converted to an integer, and then assigned to the left operand of the = operator. Hope this helps.

+5
source

This is a little duplication, but it may help to better understand:

  • round() has the following prototype:

     double round(double x); 

    therefore it returns double .

  • There is an implicit conversion from double to int to C, so the entry

     int i = round(f*100); 

    converts the result of round() to int .

  • If you have a function expecting int, e.g.

     void printMyNumber(int number) { printf("%i\n", number); } 

    you can call it like this:

     printMyNumber(round(f*100)); 

    and the implicit conversion works as expected, because the compiler sees both types (return type from round() and expected type of argument printMyNumber() ).

  • The reason this doesn't work with printf() is because the prototype printf() looks like this:

     printf(const char *format, ...); 

    therefore, with the exception of the first argument, the types of the arguments are unknown. Therefore, everything that you transmit is transmitted without conversion (except for promotions by default ). Of course, you can use a cast to perform an explicit conversion instead:

     printf("%i\n", (int) round(f*100)); // <- this is fine 
+4
source

Source: https://habr.com/ru/post/1269970/


All Articles