C语言printf()的奇怪问题???

int iVar =5;
float fVar = 5.01;
printf("%f,%d\n",(double)iVar,fVar); // (double)iVar正确输出5.000000
printf("%d,%f\n",fVar,(double)iVar); // (double)iVar错误输出0.000000??
printf("%f,%d\n",(double)iVar,5); // (double)iVar正确输出5.000000
printf("%d,%f\n",5,(double)iVar); // (double)iVar正确输出5.000000
为什么第二个printf()错误输出呢?

首先,double型的输出要用%lf。
其次,程序在调用printf输出时,是自右向左压入各个参数的值或地址的(根据参数的类型而异)。在printf执行中,只是根据格式字串里指定的格式,依次将堆栈中的那些数值取出符合该格式要求的长度、并按格式指定的类型来解释取到的数据。比如%d指定的是作为int输出,这需要2字节数据,printf只管从堆栈里取2个字节(其实这2字节可能实际是某个double型数据的一部分),然后把这两个字节作为int型的数值来输出。

在第一个printf调用时,先将4字节的float型的fVar入栈,然后将8字节的强制转换为double型的iVar入栈,最后是格式字串的地址。在printf处理过程中,根据格式字串中的不同格式,从堆栈中以此取出相应长度的数值并按该格式指定的类型将此数值输出,即先将(double)iVar的8字节中的开头4字节作为float型输出,碰巧这确实是5.0,可是继续输出时,是将(double)iVar剩下的一半的一半作为int输出,因此这个值会是错的。

第二个printf,输出的第一个数将是float型的fVar前2个字节作为int型输出的,值自然是错的,再之后又将fVar的后2个字节拼上了(double)iVar的头2个字节合起来组成的4个字节作为float型数值输出,这4个字节全部是0,所以你看到的数值就是0.000000了。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2010-08-31
这个与数据在计算机中的存储有关系,同时也与printf函数有关系,修改为printf("%d,%f\n",(int)fVar,(double)iVar); 也是OK的,具体为什么会出错我也说不清楚。建议使用到类型转化的时候就强制转换一下,以免出问题。本回答被提问者采纳
第2个回答  2010-08-31
int iVar =5;
float fVar = 5.01;
printf("%f,%d\n",(double)iVar,fVar); // (double)iVar正确输出5.000000
printf("%d,%f\n",fVar,(double)iVar); // 这个跟printf函数和编译器有关吧,在VC里面前面一个转化出错了,后面一个是正确的结果。。。这样的时候要进行强制类型转化的,结果就看编译器怎么来定了。。。
printf("%f,%d\n",(double)iVar,5); // (double)iVar正确输出5.000000
printf("%d,%f\n",5,(double)iVar); // (double)iVar正确输出5.000000
第3个回答  2010-09-01
#include<stdio.h>
void main()
{int iVar =5;
float fVar = 5.01;
printf("%f,%d\n",(double)iVar,(int)fVar);
printf("%d,%f\n",(int)fVar,(double)iVar);
printf("%f,%d\n",(double)iVar,5);
printf("%d,%f\n",5,(double)iVar); }

至于为什么,软件本身的问题,没办法,就得这样输
相似回答