首页
社区
课程
招聘
一个C语言的简单问题!求助中!
发表于: 2010-5-10 22:29 3269

一个C语言的简单问题!求助中!

2010-5-10 22:29
3269
#include <stdio.h>
void main()
{
        int ch,os=0,js=0;
        float op=0.0,jp=0.0;
        while(scanf("%d",&ch)==1)
        {
                if(ch==0)
                        break;
                else if ((ch%2)==0)
                {
                        os++;
                        op=op+ch;
                }
                else
                {
                        js++;
                        jp=jp+ch;
                }
        }
        printf("%f %#x %.0f %#x %d %#x %.0f %#x \n",os,&os,op=op/os,&op,js,&js,jp=jp/js,&jp);
}

最后这个显示地址是我加的,为了方便解决问题,大家可以去掉,好了,
进入正题,我们将最后一行的printf中的第一个%f改为%d,那么我们的程序正常运行

在此,我们先不说这个程序的健壮性,我们一般输入两个整数。

好了,如果没有改,那么我们的程序在输入两个整数后,那么我们的输入九会变成零。

很奇怪,但是在程序运行中,他存入的数据时正确的,

上面这个是改为%d的结果,下面这个是%f的结果!


大家可以看结果,从结果得知,,
其中按地址来说,我们第二次读取,的时候,第一个数的地址也应该是
12ff78
12ff78  内存地址中的数据是01 00 00 00
第一个为零,我可以想通,
但是,浮点数和整数的内存都一样,
所以,不应该影响到第二个数字显现呀。

请大家解释为什么换为%d就正常显示,

正确的代码如下

#include <stdio.h>
void main()
{
        int ch,os=0,js=0;
        float op=0.0,jp=0.0;
        while(scanf("%d",&ch)==1)
        {
                if(ch==0)
                        break;
                else if ((ch%2)==0)
                {
                        os++;
                        op=op+ch;
                }
                else
                {
                        js++;
                        jp=jp+ch;
                }
        }
        printf("%d %#x %.0f %#x %d %#x %.0f %#x \n",os,&os,op=op/os,&op,js,&js,jp=jp/js,&jp);
}

小弟经过研究,,换了一种表示方法

程序如下

#include <stdio.h>
#define N 2
void main()
{
        int os=0,js=0,flag,sr;
        float op=0.0,jp=0.0;
        while (scanf("%d",&sr)==1)
        {
                if(sr==0)
                        break;
                if((sr%N)==0)
                        flag=0;
                else
                        flag=1;
                switch(flag)
                {
                case 0: os++;
                            op=op+sr;
                                break;
                case 1: js++;
                            jp=jp+sr;
                                break;
                }
        }
//        printf("%f,%f,%d,%f\n",os,op/os,js,jp/js);
    printf("%f %#x %.0f %#x %d %#x %.0f %#x \n",os,&os,op=op/os,&op,js,&js,jp=jp/js,&jp);
}



先在我更郁闷了,为什么程序都差不多。显示的东西都一样,为什么结果会相差那么大?

正在撞墙中,等待解答!

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 360
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
rol
2
图传错了吧,我怎么看怎么一样呢,相差大的是什么?
2010-5-10 23:20
0
雪    币: 160
活跃值: (56)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
弄错了,第二个图,有问题。今天来不急改了,大家可以运行一下程序就明白了!我明天再来改第二幅图!
2010-5-10 23:24
0
雪    币: 424
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
以前讨论过,浮点数均转换成double压栈,整数均转换成int32压栈,所以他们在栈内长度是不同的
2010-5-10 23:54
0
雪    币: 360
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
rol
5
os 入栈时是 32 位
如果按%f来转换 是取的64位
所以会导致会面的参数完全对应不上。
2010-5-11 00:17
0
雪    币: 90
活跃值: (91)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
又是压栈的关系 本贴收藏了 说不定什么时候回来看看
2010-5-11 12:06
0
雪    币: 435
活跃值: (1277)
能力值: ( LV13,RANK:388 )
在线值:
发帖
回帖
粉丝
7
4楼正解
为便于分析,将问题程序简化如下
#include <stdio.h>
void main()
{
  int a=1,b=1;
  float c=1.1;
  printf("%f %d %d\n",a,b,c);
}

反汇编后
00401000  /$  68 9999F13F   push    3FF19999
00401005  |.  68 000000A0   push    A0000000
0040100A  |.  6A 01         push    1
0040100C  |.  6A 01         push    1
0040100E  |.  68 30904000   push    00409030                         ;  ASCII "%f %d %d",LF
00401013  |.  E8 08000000   call    00401020
00401018  |.  83C4 14       add     esp, 14
0040101B  \.  C3            retn


这里可以看到 不同于msdn的解释,float其实是作为64bit的double压栈的
因为长度和其他连个参数int不一致,所以显示结果当然会出问题
再看看输出结果

所以我猜测长度的不一致,导致了64位长的浮点数 被分成两个int输出,而两个1,被合并成一个64bit的浮点数输出了
3FF19999转十进制正好是1072798105
A0000000有符号十进制也正是-1610612736

问题应该在这里
上传的附件:
  • 1.png (12.79kb,42次下载)
2010-5-11 21:41
0
游客
登录 | 注册 方可回帖
返回
//