Home > Net >  Weird result of using scanf "%f" to read a float number and then assign to double
Weird result of using scanf "%f" to read a float number and then assign to double

Time:09-15

I just met a problem in C. Following is the code:

#include <stdio.h>

int main() {

    double num = 0;

    printf("Please enter a number: ");
    scanf("%f", &num);
    printf("The entered number is %f", num);

    return 0;
}

For some reason, no matter what number is entered from keyboard, the value of num keeps the same as 0. Of course, if I change the data type of num to float, then everything will be fine. But I just want to know why the above code does not work. My understanding is C automatically converts float to double, so the above code should work fine. I wonder if anybody can kindly provide further explanation.

Thanks.

CodePudding user response:

The correct scanf conversion format specifier for double is %lf, not %f. By using the wrong specifier, your program is invoking undefined behavior, which means that anything can happen (i.e. your program may crash or print wrong output).

My understanding is C automatically converts float to double

This statement is correct for printf, but not for scanf. When calling printf with a float variadic argument, the float is promoted to double. This is called a default argument promotion. However, a float * is never promoted to a double *. This applies both to printf and scanf, but is more relevant to scanf, because scanf makes more use of pointers.

The underlying reason for this behavior is that with printf, variables are passed by value, so that a float can easily be promoted to a double and printf therefore does not have to distinguish between a float and a double. However, with scanf, variables are usually passed by pointer, because scanf is not interested in the value of a variable, but rather its address, as it needs to know where to write the value of the variable. In order to write the value, scanf must also know the type and size of the variable. Therefore, scanf must distinguish between a float and a double.

CodePudding user response:

Use the %lf format specifier to read a double.

  • Related