当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 6 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : 王垠主页上的一个例子的解释,不是很明白。。。。。。。。
帖子发表于 : 2007-04-23 17:28 
头像

注册: 2006-11-22 10:57
帖子: 180
送出感谢: 0 次
接收感谢: 0 次
一个叫 1.c,内容是
#include<stdio.h>
int main()
{
float f=23.45;
printf("main: %f\n", f);
t1(f);
}

另一个是 2.c,内容是:
#include<stdio.h>
void t1(float f)
{
printf("t1: %f\n", f);
}
用 GCC 编译这两个程序到一起:
gcc 1.c 2.c
运行得到结果:
main: 23.450001
t1: 2.000000
gcc 编译如果不加 -Wall 选项就不给任何错误提示!可是它却吧 t1() 的 prototype 缺省当成了接受整型参数!
想问下:
它怎么就吧 t1() 的 prototype 缺省当成了接受整型参数?就算接受整型参数,也应该是23啊???


_________________
Ubuntu 8.04
IBM R52-18465DC
CPU:PM 1.73Ghz DDR2:768MB 533Mhz
INTEL 915GM/915PM
ATI Mobility Radeon X300 64MB
40G SATA


页首
 用户资料  
 
2 楼 
 文章标题 : Re: 王垠主页上的一个例子的解释,不是很明白。。。。。。。。
帖子发表于 : 2007-04-23 23:22 

注册: 2006-12-26 16:22
帖子: 15
送出感谢: 0 次
接收感谢: 0 次
gre_linewer 写道:
一个叫 1.c,内容是
#include<stdio.h>
int main()
{
float f=23.45;
printf("main: %f\n", f);
t1(f);
}

另一个是 2.c,内容是:
#include<stdio.h>
void t1(float f)
{
printf("t1: %f\n", f);
}
用 GCC 编译这两个程序到一起:
gcc 1.c 2.c
运行得到结果:
main: 23.450001
t1: 2.000000
gcc 编译如果不加 -Wall 选项就不给任何错误提示!可是它却吧 t1() 的 prototype 缺省当成了接受整型参数!
想问下:
它怎么就吧 t1() 的 prototype 缺省当成了接受整型参数?就算接受整型参数,也应该是23啊???
代码:
#include<stdio.h>
extern void t1(float f);
int main()
{
float f=23.45;
printf("main: %f\n", f);
t1(f);
}
即可


页首
 用户资料  
 
3 楼 
 文章标题 :
帖子发表于 : 2007-04-24 16:18 

注册: 2005-10-26 22:18
帖子: 31
送出感谢: 0 次
接收感谢: 0 次
唉,一遇到这种稍微有点难度的问题,
我就暴露菜鸟的本质了。

不过可以这样解释:

1,首先应该知道这个诡异的现象是由于没有对t1函数进行声明引起的。
如果在main函数调用t1之前,声明t1的函数原型,就不会有这种问题。

2,隐式声明。
在调用一个函数之前,没有见到对此函数的声明,不知其原型。
则把第一次调用当作隐式声明。
并且返回值为int。(C里面整型的地位比较特殊。)
至于函数参数,float要转换成double。

3,按照 IEEE 754 标准,float占4个字节,一位符号位,8位指数,23位尾数。
而double占8个字节,1个符号位,11位指数,52位尾数。
(具体的,自己再查资料吧)

这样,23.45,在内存中,float表示为41bb 999a,
即0100 0001 1011 1011 1001 1001 1001 1010
作为参数入栈时,
转换成double,
只需:
符号位不变: 0-->0
指数部分值不变,但增长为11位:1000 0011 -> 100 0000 0011
尾数原来23位,补上29个0,得到:0111 0111 0011 0011 0011 0100 0000 0000 0000 0000 0000 0000 0000
得到的double在内存中是:4037 7333 4000 0000

然后,在t1函数中,从栈中取参数,由于它认为自己的参数是float类型,
故只读了4个字节。读到4000 0000。
即0100 0000 0000 0000 0000 0000 0000 0000
按float处理,第一位0,正数,
接下来8位1000 0000,即移码的1,即指数为1。
后面全0,
即float值被认为是:1.0*10^1 (二进制),即2.0
所以输出为2.0.


_________________
HP nx 6120,
cpu CM 1.5G,
chip 915GM,
memory 512M,
harddisk 40G 5400rpm。

ubuntu 7.04 feisty,
with beryl, etc.


页首
 用户资料  
 
4 楼 
 文章标题 :
帖子发表于 : 2007-04-24 16:21 

注册: 2005-10-26 22:18
帖子: 31
送出感谢: 0 次
接收感谢: 0 次
这是我第一次打那么多01。
真累,
几十年前,
计算机刚刚出现时,
那些牛人就是整天对着数不清的001011么?


_________________
HP nx 6120,
cpu CM 1.5G,
chip 915GM,
memory 512M,
harddisk 40G 5400rpm。

ubuntu 7.04 feisty,
with beryl, etc.


页首
 用户资料  
 
5 楼 
 文章标题 :
帖子发表于 : 2007-04-24 17:19 
头像

注册: 2006-11-22 10:57
帖子: 180
送出感谢: 0 次
接收感谢: 0 次
多谢


_________________
Ubuntu 8.04
IBM R52-18465DC
CPU:PM 1.73Ghz DDR2:768MB 533Mhz
INTEL 915GM/915PM
ATI Mobility Radeon X300 64MB
40G SATA


页首
 用户资料  
 
6 楼 
 文章标题 :
帖子发表于 : 2007-04-24 17:21 
头像

注册: 2006-11-22 10:57
帖子: 180
送出感谢: 0 次
接收感谢: 0 次
多谢


_________________
Ubuntu 8.04
IBM R52-18465DC
CPU:PM 1.73Ghz DDR2:768MB 533Mhz
INTEL 915GM/915PM
ATI Mobility Radeon X300 64MB
40G SATA


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 6 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 3 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译