QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1011|回复: 11

float类型的值作为参数传入函数为什么值会变?

[复制链接]
发表于 2004-10-19 05:34:16 | 显示全部楼层 |阅读模式
main.c
[code:1]
main()
{
    float a,b,c;
    a=1.0;
    b=1.0;
    c=1.0;
    test(a,b,c);
}
[/code:1]
test.c
[code:1]
void test(float a,float b,float c)
{
    printf("a=%f b=%f c=%f\n",a,b,c);
}
[/code:1]

gcc main.c test.c -o test
./test的结果是
a=0.000000 b=1.875000 c=0.000000
这是为什么?换成double,int都没问题。或者把test定义放在main.c里也没问题。
 楼主| 发表于 2004-10-19 05:35:59 | 显示全部楼层
环境是redhat9.0
回复

使用道具 举报

发表于 2004-10-19 06:34:37 | 显示全部楼层
[code:1]
main()
{
    float a,b,c,d;
    a=1.0;
    b=1.0;
    c=1.0;
    d=1.0;
    test(a,b,c,d);
}
[/code:1]
[code:1]
void test(float a,float b,float c,float d)
{
    printf("a=%f b=%f c=%f d=%f\n",a,b,c,d);
}
[/code:1]
出现a=0.000000 b=1.875000 c=0.000000 d=1.875000
看来是有规律的,难不成是堆栈哪里出错了???!!!
回复

使用道具 举报

发表于 2004-10-19 08:48:21 | 显示全部楼层
我测试了一下,
即使换成
a=1.0
b=2.0
c=3.0
结果也是一样的,一时间不知道为什么?
帮你顶一下吧,
我的环境是 Windows 2000 + cygwin
回复

使用道具 举报

发表于 2004-10-19 08:59:39 | 显示全部楼层
main()里要加句
void test(float,float,float);
就好了
回复

使用道具 举报

发表于 2004-10-19 09:11:37 | 显示全部楼层
正确的写法
[code:1]
#include <stdio.h>

void test (float, float, float);


int main()
{
    float a,b,c;
    a=1.0;
    b=1.0;
    c=1.0;
    test(a,b,c);
}


void test(float a,float b,float c)
{
    printf("a=%f b=%f c=%f\n",a,b,c);
}
[/code:1]

你没有在main之前写test的定义,虽然最终ld可以找到test的实现,但在编译main时由于不知道test的定义,所以编译器无法为调用test正确的对参数压栈。
回复

使用道具 举报

发表于 2004-10-19 09:20:17 | 显示全部楼层
楼上的,楼主的问题是,分成2个文件的。不是在一个文件里面,
做一个头文件的话,这个问题就解决了

我现在的疑问是:为什么,没有头文件,main.c也不包括那个函数声明,为什么会出现这个结果?
回复

使用道具 举报

发表于 2004-10-19 09:39:09 | 显示全部楼层
[quote:88d1b45879="daixi"]楼上的,楼主的问题是,分成2个文件的。不是在一个文件里面,
做一个头文件的话,这个问题就解决了

我现在的疑问是:为什么,没有头文件,main.c也不包括那个函数声明,为什么会出现这个结果?[/quote]

我已经说了,呵呵,main函数没有test的定义,所以不知道该如何对参数压栈,跟放在多个文件里没有关系。用objdump反汇编一下就能看到,正确时应该每个参数压4个字节,没有test的定义时,每个参数留了8个字节的空间。
回复

使用道具 举报

 楼主| 发表于 2004-10-19 11:34:06 | 显示全部楼层
哈,明白了,像这样的东西应该在那里能学到?
回复

使用道具 举报

发表于 2004-10-19 12:09:41 | 显示全部楼层
[quote:8b0506e098="mozilla"]哈,明白了,像这样的东西应该在那里能学到?[/quote]

我是在学习那个著名的栈溢出安全漏洞的原理和偶尔学习linux内核时获得这方面知识的,要提一句,binutilits里面那些小工具都非常强大,objdump就是其中之1,作为使用c的程序员,一定要掌握啊。
回复

使用道具 举报

发表于 2004-10-26 22:57:26 | 显示全部楼层
谢谢版主的回答
回复

使用道具 举报

发表于 2004-10-27 12:50:09 | 显示全部楼层
我也学到东西了!谢谢!
回复

使用道具 举报

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

本版积分规则

GMT+8, 2024-11-7 05:26 , Processed in 0.071929 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

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