1

我为此使用带有 gcc 的 Netbeans,我发现函数参数的值在调用函数和被调用函数之间被破坏了。

在 myfuns.h 中:

float dotprod( float u1, float u2, float u3,  float v1, float v2, float v3 );

在 myfuns.c 中

 float dotprod( float u1, float u2, float u3, float v1, float v2, float v3 )
 {
    float res= u1*v1+u2*v2+u3*v3 ;
    return res;
 }

在 main.c

 ...
 float dp=dotprod( rx, ry, rz,  ddx, ddy, ddz );
 ...

如果我在 dotprod() 函数中打印 u1,u2 等的值,或者使用调试器检查它们,则这些值与 main.c 中的 rx,ry 等的值不同

如果我将参数从 float 转换为 float*,问题似乎就消失了。我还尝试在 6 个浮点参数之前和之后添加一个虚拟整数参数,第一个可以,但最后一个也会损坏。我花了几个小时试图找出错误。

有什么建议么 ?

4

2 回答 2

1
  1. 所有这些变量的类型是否main()指定为float
  2. 调用原型dotprod()时是否可见?换句话说,你的主文件有#include "myfuns.h"吗?

特别是,对第二个问题回答“否”意味着编译器将对传递的参数做出某些假设,从而使值具有不同的宽度,或者以不同的方式解释它们。

例如,考虑:

#include <stdio.h>

int main(int argc, char *argv[]) {
    float x = 1.5, y = 2.5;
    fn (x, y);                       // <-- compiler makes assumptions.
    return 0;
}

void fn (float a, float b) {         // <-- compiler should complain
    printf ("%f %f\n", a, b);        //     about bad assumptions.
}

输出:

0.000000 1.937500

这真的不是你所期望的。这是用 gcc 编译的,并且吐出的大量警告应该有足够的理由返回并检查代码(a)

在这种特殊情况下, myintfloattypes 具有相同的宽度(32 位),但是因为编译器认为函数接受int,所以它会首先将这些浮点数转换为该类型。不幸的是,当函数查看int堆栈上的这些值时,它会将它们解释为float类型,它们的编码方式完全不同。

如果您的预期类型和实际类型的宽度不同,情况可能会更糟,因为您可能会发现您尝试使用的数据多于放入堆栈的数据。

只需插入以下内容即可修复此特定代码示例:

void fn (float, float);

之前main()(或交换main()fn()周围),以便不假定原型。这不会导致来自 gcc 的警告和正确的输出:

1.500000 2.500000

基本上,您必须确保调用者和被调用者就传递的参数达成一致。这包括调用约定、数据类型和参数计数等。这些中的任何一个不匹配都会给您带来问题。


(a):例如以下,在我的系统上:

testprog.c: In function ‘main’:
testprog.c:5: warning: implicit declaration of function ‘fn’
testprog.c: At top level:
testprog.c:9: warning: conflicting types for ‘fn’
testprog.c:5: note: previous implicit declaration of ‘fn’ was here
于 2012-10-09T06:23:35.367 回答
0

确保您使用函数参数传递相同类型的数据,即大小和表示。

对于一个非常简单的测试,请在 main 中尝试:

float dp=dotprod( (float)rx, (float)ry, (float)rz,  (float)ddx, (float)ddy, (float)ddz );
于 2012-10-09T06:38:48.253 回答