繁体   English   中英

在c函数中传递参数

[英]Passing arguments in c functions

我是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 test GridDim.o

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

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

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

原因是除非编译器有一个声明参数类型的函数原型,否则它会将所有浮点数提升为双精度数。 在运行时,你的浮点数被提升为双精度数,然后传递给GridDim,它读取double的前半部分并将其解释为float。 如果在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__*/

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

#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

你缺少功能声明。 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

正如我在评论中所说, C中的类型cast (int)会进行修剪,例如(int)0.9 == 0 在这里,您可能希望使用math.h提供的函数round

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

#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);
}

编辑:

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

6.3.1.4实际浮动和整数

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

AGAING EDITED:

但是我必须说你的原始代码在我的机器上产生你的正确答案。 请注意,此问题实际上是由与机器相关的浮点数计算生成的:

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

所以当它是5.000002 ,你的类型转换(int)x工作,因为它只是将结果转换为5 ,但是当它是4.999998时它将被转换为4 round总能产生你期望的答案。

再次编辑:

哦对不起,我没有指出你问题的确切原因! 你错过了函数定义。 在这里,我投票支持@ Gangadhar的回答。

在将值存储在变量中之前,您必须采用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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM