鱼C论坛

 找回密码
 立即注册
查看: 8006|回复: 41

[技术交流] C语言谜题系列1

  [复制链接]
发表于 2011-7-25 11:57:36 | 显示全部楼层 |阅读模式
10鱼币
本帖最后由 仰望天上的光 于 2011-7-25 11:58 编辑

说明:为了增加各位鱼油的C语言基本功,我打算出一系列的C语言谜题(所有题目都是基于32位的C编译器,所以不保证在TURBO C下各个程序的行为),涉及到C语言的大部分阴暗面(目的不是打击C语言,而是让大家更了C语言,不至于陷入类似的陷进),每次首先解决谜题的鱼油获得全部的悬赏奖励,希望大家喜欢这个系列的活动。不废话了,本次的题目是这样的:以下程序将输出什么?并说明理由。


  1. #include<stdio.h>
  2. int main( void ){
  3.   int start = 2000000000;
  4.   int count=0;
  5.   float f;
  6.   for(f=start;f<start+50;++f)
  7.     count++;
  8.   printf("%d\n",count);
  9.   return 0;
  10. }
复制代码

最佳答案

查看完整内容

我修改了一下代码,发现了一个问题! 代码如下: 其输出的结果: 大家看看,这for循环中,f的值是没有加1的,所以f一直小于start+50,所以,这个循环是死循环。因此,在VC++编译器里,上诉代码是没有输出结果的。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-7-25 11:57:37 | 显示全部楼层
我修改了一下代码,发现了一个问题!
代码如下:
  1. #include<stdio.h>
  2. int main( void )
  3. {
  4. int start = 2000000000;
  5. int count=0;
  6. float f;
  7. int flag=0;
  8. for(f=start;f<start+50;++f,flag++)
  9. {

  10. printf("\n%f\n",f);
  11. count++;
  12. if(flag>50)
  13. break;

  14. }

  15. }
复制代码
其输出的结果:
QQ截图20110729035227.png

大家看看,这for循环中,f的值是没有加1的,所以f一直小于start+50,所以,这个循环是死循环。因此,在VC++编译器里,上诉代码是没有输出结果的。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2011-7-25 12:20:10 | 显示全部楼层
坐等答案...~!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2011-7-25 13:25:50 | 显示全部楼层
2000000048?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2011-7-25 14:38:21 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2011-7-26 13:08:21 | 显示全部楼层
count加1后,f加1;这样循环50次。仰光,为什么要把f定义为float型呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2011-7-26 15:15:51 | 显示全部楼层
5楼分析得不对(出现在这里的题目绝对不会是像你想得那么简单)。
提示:把f定义为float类型而非int类型是这个题目的关键所在。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2011-7-27 20:17:34 | 显示全部楼层
没返回值?。。。郁闷啊,看来道行太低了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2011-7-27 21:16:03 | 显示全部楼层
猜想:是不是int类型的2000000000转换为二进制,然后通过float类型在内存的表示方法,得出转换为float的二进制,然后再转回十进制,然后循环
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2011-7-27 21:42:34 | 显示全部楼层
这个程序.............
我输出的结果是50,不过start为何值  结果都为50;如果把f=start+50改为start+100  结果就是100;
可是我用GDB调试,f的值竟然不变,count竟然无限大;
我纳闷的一点是,int类型的范围貌似没那么大,我编译环境int类型取值最大为32767;
可是令我奇怪的是200~~~~~竟然不溢出,你说把f设为float是问题所在,可是我改为int貌似也没问题;
很纠结,纠结这个过程!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2011-7-27 22:14:53 | 显示全部楼层
zfzhuman123 发表于 2011-7-27 21:42
这个程序.............
我输出的结果是50,不过start为何值  结果都为50;如果把f=start+50改为start+100  ...

你用啥么编译器?有输出值?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2011-7-27 22:48:38 | 显示全部楼层
我用的是vc6.0编译的,根本就没有输出,进入 了无限循环。我重看了一下c的数据类型和自己写了一些代码来调试,因为本人学c不久,所以说下我这个初学者的看法:float在电脑的储存是32位,其中8位是用来放符号和指数的,所以剩余的部分只有24位,不足以存放2000000000;则实际上只是2000000(这是我的猜想,我用打印语句时能把2000000000打印出来,但我用一些语句来进行比较大小时2000000050的float是小于int的),所以它一直小于start+50.便没有输出值。要是你把f的数据类型改成double或将start的值改成2000000就会得到50,这不知道这样的想法对不对,希望和大家交流下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2011-7-28 11:42:36 | 显示全部楼层
JX机械 发表于 2011-7-27 22:48
我用的是vc6.0编译的,根本就没有输出,进入 了无限循环。我重看了一下c的数据类型和自己写了一些代码来调试 ...

很好,说得很接近了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2011-7-28 12:27:23 | 显示全部楼层
用一个int型的start来装这么大的数,结果肯定是未知的负数了,而用float类型的f 来装这2e溢出的数据是可以装下的,所以到循环的时候应该是个未知的很大的无限循环,所以在VC6下就是一直为黑屏而无输出。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2011-7-28 12:54:56 | 显示全部楼层
q369965658 发表于 2011-7-28 12:27
用一个int型的start来装这么大的数,结果肯定是未知的负数了,而用float类型的f 来装这2e溢出的数据是可以装 ...

32位的int是可以装下这个数的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2011-7-28 13:44:10 | 显示全部楼层
仰望天上的光 发表于 2011-7-28 12:54
32位的int是可以装下这个数的。

哦,32位的,其实答数你也说了一些了,既然你前面提到把f声明为float就是重点,就是告诉大家在由int转换为float时的精度会发生变化,而精度的变化上面的同学也已经说了,我也就不啰嗦了,换名话说,(float)2000000000 == 2000000050,因此表达式f 小于strat+ 50在第一次执行循环体之前就是不成立的,所以,循环体也就永远没有机会去运行,应该也就是输出0,而把它改成double,就没有精度丢失的问题了,会直接得出结果也就是50.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2011-7-28 15:00:58 | 显示全部楼层
我是来偷东西的
哈哈
有偷到一点

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2011-7-28 16:55:19 | 显示全部楼层
呵呵,本来想放下的了,但看到LZ的回复,便忍不住再想了想这段代码。虽然我学c不久,但现在我肯定这个问题是出在这两种数据的不同的储存方式引发的。我自己写了些代码来测试发现float的2000000000和2000000050是等大的,我就查了下资料,又知道了单精度浮点数最多的十进制数的有效数字只有7位,超出的会四舍五入(也不知道这个和编译器有没关系),所以便会出现了我昨晚所说的情况,f一直小于start+50;则没有输出。呵呵,即使没答对,我还是学会到了许多东西,哈哈哈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2011-7-29 09:13:48 | 显示全部楼层
18楼很不错哦,这个题目有两个要点,你已经发现其中比较重要的那个了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2011-7-29 17:21:02 | 显示全部楼层
仰望天上的光 发表于 2011-7-29 09:13
18楼很不错哦,这个题目有两个要点,你已经发现其中比较重要的那个了。

另外的话float型的数据在内存的表现形式吧。如果是20亿,在内存里存放方式应该是:数符为+ ,小数部分为.2,指数部分为10。因为小数部分为.2所以占用2个位就能变现出来了。但加上1,20亿零1。这样的话,小数部分存放的书应该未.2000000001,这样的话,就需要32位来表达了。就会出现失精。这应该是C语言存在的缺陷吧。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-20 00:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表