-1

The following program is supposed to read a float, then prints an integer. But when I run it, it doesn't print the integer. Instead it prints the value that I entered in scanf. Can anyone explain the output?

#include<stdio.h>
void main()
{
    long x;
    float t;
    scanf("%f",&t);
    printf("%d\n",t);
    x=90;
    printf("%f\n",x);
    {
        x=1;
        printf("%f\n",x);
        {
            x=30;
            printf("%f\n",x);
        }
    x=9;
    printf("%f\n",x);
    }
}
5
  • Yes, we can. But we won't as you're asking this question at the wrong place. Please ask this on CodeReview instead. Commented Aug 15, 2012 at 13:17
  • 1
    have you looked up the documentation for the functions that are being used? What specifically don't you understand? Commented Aug 15, 2012 at 13:17
  • Not sure what you mean. However you are using a floating point format to print out a long variable and that will not work correctly. Use %d rather than %f when printing x. Commented Aug 15, 2012 at 13:17
  • Take a look on a printf flags. cplusplus.com/reference/clibrary/cstdio/printf Commented Aug 15, 2012 at 13:17
  • @H2CO3 No, Code Review only does reviews of code with no known bugs. This question would be off-topic on Code Review, but it is on-topic here. Commented Aug 15, 2012 at 13:27

4 Answers 4

3

t has type float, so printf("%d\n",t) invokes undefined behaviour, since %d expects an argument of type int. Anything can happen. (The same is true of printf("%f\n",x): %f expects a double, but the type of x is long int.)

I once answered one of those cases in detail; perhaps that's of some interest. The upshot is that in practice you can explain the observed behaviour by studying the anatomy of IEEE754 floating point numbers, and by knowing the sizes of integral types on your platform.

Sign up to request clarification or add additional context in comments.

Comments

1
printf("%f\n",x);

x has the type long, but the %f converter expects a floating-point value (of type double). Normally, when you pass an integer to a function that expects a floating-point value, the value is silently converted. However, this only applies to functions with a fixed number of arguments and a prototype indicating what the type of each argument is. It does not apply to variadic functions such as printf, because the compiler doesn't have enough information to know what to convert the value to: the format string may only be analyzed at runtime.

The language specification leaves the behavior of this program undefined: it can do anything. What is probably happening in this case is that x is stored in some integer register, and f is stored in some floating-point register. Since the printf calls are looking for a floating-point value, the compiled code goes to look in the first floating-point register. If you had passed a floating-point value to printf, the argument would end up in that register. But you didn't, so the value in that register was the last value that was stored there: the value read by scanf.

A good compiler would warn you that you're doing something wrong. For example, here's what I get when I compile your code with gcc -O -Wall:

a.c:2: warning: return type of 'main' is not 'int'
a.c: In function 'main':
a.c:7: warning: format '%d' expects type 'int', but argument 2 has type 'double'
a.c:9: warning: format '%f' expects type 'double', but argument 2 has type 'long int'
a.c:12: warning: format '%f' expects type 'double', but argument 2 has type 'long int'
a.c:15: warning: format '%f' expects type 'double', but argument 2 has type 'long int'
a.c:18: warning: format '%f' expects type 'double', but argument 2 has type 'long int'

I recommend configuring your compiler to print such warnings and paying attention to them.

To make your program work, either pass a floating-point value where one is expected, or tell printf to expect an integer value. Either

printf("%f", (double)x);

or

printf("%ld", x);

Comments

1

You should use %d when printing an int variable, like this:

printf("%ld", x);

You are using %f.

2 Comments

I would say printf("%ld", x);
Since it is long, yes, you are correct. Thanks for the clarification! Will update.
0

x is a long integer yet you're printing it as a float. And t is a float yet you're printing it as an integer. Switch the %d and %f format specifiers in your printf calls.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.