简体   繁体   English

在c函数中传递参数

[英]Passing arguments in c functions

I'm newbie in c. 我是c的新手。 I have written a function in c and passes the arguments to it but I got different answers as I expect. 我已经在c中编写了一个函数并将参数传递给它,但我得到了不同的答案。

The function is 功能是

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

I used gcc to compile it: gcc -c GridDim.c 我使用gcc编译它:gcc -c GridDim.c

then I used the object file for a main file and compile that file 然后我使用目标文件作为主文件并编译该文件

#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 gcc test.c -o test GridDim.o

but I did not get the correct answer. 但我没有得到正确的答案。 Does anybody know why? 有人知道为什么吗?

the answer should be m=101 n=51 k=4 but I got m=1 n=1 k=-12 答案应该是m = 101 n = 51 k = 4但我得到m = 1 n = 1 k = -12

You need to declare a function prototype for your GridDim function and include it in the file that contains your main method. 您需要为GridDim函数声明一个函数原型,并将其包含在包含main方法的文件中。

The reason is that unless the compiler has a function prototype that declares the types of the arguments it will promote all floats into doubles. 原因是除非编译器有一个声明参数类型的函数原型,否则它会将所有浮点数提升为双精度数。 At run-time your floats gets promoted into doubles and then passed to GridDim which reads the first half of the double and interprets it as a float. 在运行时,你的浮点数被提升为双精度数,然后传递给GridDim,它读取double的前半部分并将其解释为float。 If you print the values inside GridDim you will see that the floats come in as corrupted values. 如果在GridDim中打印值,您将看到浮点数作为损坏的值进入。

If you declare your method in a header file, eg GridDim.h: 如果在头文件中声明方法,例如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__*/

... and #include it in GridDim.c (to ensure that the definition matches the declaration): ...和#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);
}

... and #include it in Main.c to ensure that the call matches the declaration: ...并在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;
}

... then the arguments will be passed correctly to the GridDim function. ...然后参数将正确传递给GridDim函数。 I added some printf statements so that you can see this. 我添加了一些printf语句,以便您可以看到这一点。

If you comment out the #include "GridDim.h" in Main.c then you will see what is happening in your current version of the code: 如果您在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

With the #include the output looks like this: 使用#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

You are missing declaration of function. 你缺少功能声明。 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);

And compile both files at a time 并一次编译两个文件

gcc main.c griddim.c -o result
./result

As I've said in the comments, the type cast (int) in C does trimming, eg (int)0.9 == 0 . 正如我在评论中所说, C中的类型cast (int)会进行修剪,例如(int)0.9 == 0 Here you may want to use the function round provided by math.h 在这里,您可能希望使用math.h提供的函数round

The following code solves your problem. 以下代码解决了您的问题。

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

EDITED: 编辑:

Here's it's specified in the standard document, in Section 6 of ISO/IEC 9899:TC2 : 这是在ISO/IEC 9899:TC2第6节中的标准文档中指定的:

6.3.1.4 Real floating and integer 6.3.1.4实际浮动和整数

1 When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (ie, the value is truncated toward zero). 1当实际浮动类型的有限值转换为_Bool以外的整数类型时,小数部分将被丢弃(即,该值被截断为零)。 If the value of the integral part cannot be represented by the integer type, the behavior is undefined.50) 如果整数部分的值不能用整数类型表示,则行为未定义.50)

AGAING EDITED: AGAING EDITED:

However I have to say that your original code produces your-correct-answers on my machine. 但是我必须说你的原始代码在我的机器上产生你的正确答案。 Please notice this problem is actually generated by the machine-dependent floating point number calculation: 请注意,此问题实际上是由与机器相关的浮点数计算生成的:

Assuming your're calculating the product of 1.0 and 5.0 : float x = 1.0 * 5.0 . 假设您正在计算1.05.0的乘积: float x = 1.0 * 5.0 Here due to the precision, your actual result MAY BE 5.000002 or 4.999998 , depends on the platform that runs this code. 由于精度,您的实际结果可能是5.0000024.999998 ,取决于运行此代码的平台。

So when it's 5.000002 , your type cast (int)x works since it just cast the result to 5 , however when it's 4.999998 it would be casted to 4 . 所以当它是5.000002 ,你的类型转换(int)x工作,因为它只是将结果转换为5 ,但是当它是4.999998时它将被转换为4 And round would always produce your expected answers. round总能产生你期望的答案。

AGAIN EDITED: 再次编辑:

Oh sorry I'm not pointing the exact reason of your problem! 哦对不起,我没有指出你问题的确切原因! You're missing the function definition. 你错过了函数定义。 Here I vote for @Gangadhar's answer. 在这里,我投票支持@ Gangadhar的回答。

before storing the value in the variable you have to take ceil value. 在将值存储在变量中之前,您必须采用ceil值。 because in c 0.9999 value if you are converting into the int it will convert to zero so before storing the value you have to take ceil value. 因为在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