2

i wrote the following program

 #include <stdio.h>

 main()
 {
 int i = 2;
 float c = 4.5;
 printf("%d\n",c);
 printf("%f\n",i);
 return 0;
 }

though i know this is the wrong practice,when i run the program i got the answer as

0
4.500000

but when i exchanged the printf statements a little bit this way

#include <stdio.h>

main()
{
int i = 2;
float c = 4.5;
printf("%f\n",i);
printf("%d\n",c);
return 0;
}

the output was

0.000000
0

i couldn't understand whats happening ,any one pls explain me.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
raghu
  • 431
  • 2
  • 11
  • 23
  • You need to check how floating point is represented http://en.wikipedia.org/wiki/Floating_point – George Kastrinis Aug 29 '11 at 16:03
  • 3
    Playing with undefined behavior, are we? Why are you so interested what exactly is happening? Instead of that, you could spend time to learn to code ***well***, not using anything that causes undefined behavior, and there's a ***lot*** to learn there, so, my vote goes for "don't waste your time on this" – Armen Tsirunyan Aug 29 '11 at 16:05
  • @Armen Tsirunyan.....u r right...but coding can also be learned from abnormal behaviors,to be exact you will know how the compiler behaves.if you trying to accept everything it gives ,then its called mugging up! – raghu Aug 29 '11 at 16:36

5 Answers5

7

printf doesn't convert it's arguments. It's looking at the memory containing a float and printing it as if it were an integer - it's like taking an MP3 file and asking word to open it as if it were a doc.

A floating point number is stored in a completely different way in memory to an integer - it's not just an integer with some decimal points

Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
6

Using incorrect format descriptors results in an Undefined Behavior.
Undefined Behavior means the behavior cannot be explained. It might work it might not or give unpredictable results, this behavior can vary anyhow, it cannot be explained in portable conclusive way for all compilers.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 3
    It can be explained quite well. It looks in memory and it tries to interpret what it find there as the format you specified. – George Kastrinis Aug 29 '11 at 16:09
  • 1
    To be fair, it *can* be explained by taking a look at the machine code that the compiler generated. It's just that one can't extrapolate from this and draw any useful conclusions. – Oliver Charlesworth Aug 29 '11 at 16:09
  • @George Kastrinis: You cannot unless you dig deep in to machine code. – Alok Save Aug 29 '11 at 16:10
  • Is knowing the representation of floating point which is a standard "diggin deep down in to machine code"? – George Kastrinis Aug 29 '11 at 16:11
  • 1
    @Oli Charlesworth: Is it not defined as Undefined Behavior? One could dig in to the machine code of a *particular* compiler and deduce conclusions about the behavior on that *particular* compiler, Can we expect these results to be uniform across all compilers? I don't think so. – Alok Save Aug 29 '11 at 16:12
  • Floating points will be represented the same way in each compiler. In fact it is not up to the compiler to decide about their representation. – George Kastrinis Aug 29 '11 at 16:14
  • @Als: That's what I mean by "one can't extrapolate from this and draw any useful conclusions". – Oliver Charlesworth Aug 29 '11 at 16:14
  • @George kastrinis: Please check my comment to Oli. – Alok Save Aug 29 '11 at 16:14
  • @George: Technically, yes it is up to the compiler. – Oliver Charlesworth Aug 29 '11 at 16:14
  • @Oli Charlesworth: Right, So Is it wrong to say that results cannot be explained? I don't mean to get in to the pedantic details of this and I will delete this answer If I am wrong, but I do think in this case it is Undefined Behavior & once you say that all bets are off, isn't that the very definition of Undefined Behavior in the standard? – Alok Save Aug 29 '11 at 16:16
  • @Als: Agreed. The only part of your answer I was taking issue with is "it cannot be explained". – Oliver Charlesworth Aug 29 '11 at 16:17
  • @George: Also, it is evident that the behaviour the OP observes is not purely explained by `printf` reinterpreting memory contents. – Oliver Charlesworth Aug 29 '11 at 16:18
  • @Oli Charlesworth: Thanks. I will modify it to *cannot be explained in portable conclusive way for all compilers* Does that seem more accurate? – Alok Save Aug 29 '11 at 16:19
  • @Als: Yes, that sounds better. – Oliver Charlesworth Aug 29 '11 at 16:20
  • @Oli Charlesworth: Modified & Thanks for the comment, Constructive comments like yours devoid of unreasonable arguments but based on facts makes us all learn better each day :) – Alok Save Aug 29 '11 at 16:22
2

an integer and a float have a different internal representation, so you must not mistake the printf %f with %d to avoid unpredictable results. People uses C expecially because C is fast, and it is fast just because it leave all under the programmer responsibility. So don't expect printf do some magic conversion under the hood because it just won't.

Felice Pollano
  • 32,832
  • 9
  • 75
  • 115
2

Basically, the format placeholder is an instruction to the function about how to retrieve and interpret the next chunk of memory from the variable length argument list. It expects the format to be exactly what you tell it. When you retrieve memory in unintended ways, you can cause all sorts of issues and undefined behavior. This is why printf and its ilk are exploitable.

Poodlehat
  • 360
  • 1
  • 2
  • 9
0

Basically, format controls replace the placeholder according to specified data type.

  • %d expects argument of type int
  • %f expects argument of type double

So Good way of doing this is

#include <stdio.h>

int main(){
   int i = 2;
   float c = 4.5;
   printf("%d\n",i);
   printf("%f\n",c);
   return 0;
}
Shushant
  • 1,625
  • 1
  • 13
  • 23