3

我是c的新手。我在 c 中编写了一个函数并将参数传递给它,但我得到了不同的答案,如我所料。

功能是

void GridDim(float long1, float long2, float dx,
             float lat1, float lat2, float dy,
             float depth1, float depth2, float dh,
             int *m, int *n, int *k)
{
    *m = (int) ((long2-long1)/dx+1);
    *n = (int) ((lat2-lat1)/dy+1);
    *k = (int) ((depth2-depth1)/dh+1);
}

我用 gcc 编译它: gcc -c GridDim.c

然后我将目标文件用于主文件并编译该文件

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
 int m,n,k;
 GridDim(20.0,30.0,0.1,10.0,15.0,0.1,5.0,20.0,5.0,&m,&n,&k);
 printf("m= %d\nn= %d\nk= %d\n", m, n, k);
 return 1;
}

gcc test.c -o 测试 GridDim.o

但我没有得到正确的答案。有人知道为什么吗?

答案应该是 m=101 n=51 k=4 但我得到 m=1 n=1 k=-12

4

4 回答 4

4

您需要为您的 GridDim 函数声明一个函数原型,并将其包含在包含您的 main 方法的文件中。

原因是除非编译器有一个声明参数类型的函数原型,否则它将把所有浮点数提升为双精度数。在运行时,您的浮点数被提升为双精度数,然后传递给 GridDim,后者读取双精度数的前半部分并将其解释为浮点数。如果您在 GridDim 中打印值,您将看到浮点数作为损坏的值出现。

如果您在头文件中声明您的方法,例如 GridDim.h:

#ifndef __GRID_DIM_DOT_H__
#define __GRID_DIM_DOT_H__

extern void GridDim(float long1, float long2, float dx, float lat1, float lat2, float dy, float depth1, float depth2, float dh, int* m, int* n, int* k);

#endif/*__GRID_DIM_DOT_H__*/

...并在 GridDim.c 中 #include (以确保定义与声明匹配):

#include <stdio.h>
#include "GridDim.h"

void GridDim(float long1, float long2, float dx,
             float lat1, float lat2, float dy,
             float depth1, float depth2, float dh,
             int *m, int *n, int *k)
{
    printf("long1 =  %10.6f\n", long1);
    printf("long2 =  %10.6f\n", long2);
    printf("dx =     %10.6f\n", dx);
    printf("lat1 =   %10.6f\n", lat1);
    printf("lat2 =   %10.6f\n", lat2);
    printf("long1 =  %10.6f\n", dy);
    printf("depth1 = %10.6f\n", depth1);
    printf("depth2 = %10.6f\n", depth2);
    printf("dh =     %10.6f\n", dh);

    *m = (int) ((long2-long1)/dx+1);
    *n = (int) ((lat2-lat1)/dy+1);
    *k = (int) ((depth2-depth1)/dh+1);
}

...并在 Main.c 中 #include 它以确保调用与声明匹配:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "GridDim.h"

int main()
{
 int m,n,k;
 GridDim(20.0f,30.0f,0.1f,10.0f,15.0f,0.1f,5.0f,20.0f,5.0f,&m,&n,&k);
 printf("m= %d\nn= %d\nk= %d\n", m, n, k);
 return 1;
}

...然后参数将正确传递给 GridDim 函数。我添加了一些 printf 语句,以便您可以看到这一点。

如果您在 Main.c 中注释掉 #include "GridDim.h",那么您将看到当前版本的代码中发生了什么:

long1 =    0.000000
long2 =    0.000000
dx =      -0.000000
lat1 =     0.000000
lat2 =     0.000000
long1 =   -0.000000
depth1 =   0.000000
depth2 =   0.000000
dh =       0.000000
m= 1
n= 1
k= -2147483648

使用#include,输出如下所示:

long1 =   20.000000
long2 =   30.000000
dx =       0.100000
lat1 =    10.000000
lat2 =    15.000000
long1 =    0.100000
depth1 =   5.000000
depth2 =  20.000000
dh =       5.000000
m= 101
n= 51
k= 4
于 2013-09-28T09:53:29.230 回答
3

您缺少函数声明。 Declare function before main()

void GridDim(float long1, float long2, float dx,
           float lat1, float lat2, float dy,
             float depth1, float depth2, float dh,
             int *m, int *n, int *k);

并一次编译两个文件

gcc main.c griddim.c -o result
./result
于 2013-09-28T09:08:57.310 回答
1

正如我在评论中所说的那样,输入的类型会(int)进行C修剪,例如(int)0.9 == 0. 在这里你可能想使用由round提供的功能math.h

以下代码解决了您的问题。

#include <math.h>
void GridDim(float long1, float long2, float dx,
             float lat1, float lat2, float dy,
             float depth1, float depth2, float dh,
             int *m, int *n, int *k)
{
    *m = round((long2-long1)/dx+1);
    *n = round((lat2-lat1)/dy+1);
    *k = round((depth2-depth1)/dh+1);
}

编辑:

这是标准文档第 6 节中指定的ISO/IEC 9899:TC2

6.3.1.4 实浮点数和整数

1 当实浮点类型的有限值转换为_Bool 以外的整数类型时,小数部分被丢弃(即,该值被截断为0)。如果整数部分的值不能用整数类型表示,则行为未定义.50)

再次编辑:

但是我不得不说你的原始代码在我的机器上产生了你的正确答案。请注意这个问题实际上是由机器相关的浮点数计算产生的:

假设您正在计算和的1.0乘积5.0float x = 1.0 * 5.0。由于精度,您的实际结果可能是5.0000024.999998,取决于运行此代码的平台。

因此,当它是 时5.000002,您的类型(int)x转换有效,因为它只是将结果转换为5,但是当它是时4.999998,它将被转换为4. 并且round总是会产生您预期的答案。

再次编辑:

哦,对不起,我没有指出您问题的确切原因!您缺少函数定义。在这里,我投票给@Gangadhar 的答案。

于 2013-09-28T09:15:21.010 回答
0

在将值存储在变量中之前,您必须获取 ceil 值。因为在 c 0.9999 值中,如果您要转换为 int,它将转换为零,因此在存储该值之前,您必须获取 ceil 值。

void GridDim(float long1, float long2, float dx,
             float lat1, float lat2, float dy,
             float depth1, float depth2, float dh,
             int *m, int *n, int *k)
{

   *m = (int) (ceil((long2-long1)/dx)+1);
   *n = (int) (ceil((lat2-lat1)/dy)+1);
   *k = (int) ((depth2-depth1)/dh+1);
}
于 2013-09-28T09:47:27.837 回答