C函数只定义返回没有预期?

时间:2016-12-15 12:20:10

标签: c gcc

下面的代码尝试一个简单的操作,将float-point 1.0与函数get_number的返回值进行比较。

我只定义了get_number函数而没有声明,因此函数get_number的返回类型是int而不是double,所以最终输出是{{1不是0

但是如果我在1文件中声明了函数get_number,它就会被罚款。

请提前帮助或尝试提供一些解释它的想法。

main.c中:

func.h

func.c:

#include <stdlib.h>
#include "func.h"

int main() {
    printf ("%d\n", 1.0 == get_number(1.0));

    return 0;
}

func.h:

double get_number(double n) {
    return n;
}

输出

  

0

注意:
平台:Linux
gcc版本:4.8.5

2 个答案:

答案 0 :(得分:1)

正如其他人所说,省略函数声明不再有效。

但是,当你省略声明时,gcc只会发出警告。进一步的gcc将假设该函数将返回int

因此,当您运行程序时,main中的代码需要函数返回int,但该函数确实返回double。换句话说,您的代码会将float视为int

以下代码说明了在阅读double时可能发生的情况,就好像它是int类型一样:

#include <stdio.h>
#include <string.h>

int main(void) {
  double d;
  int i;

  printf ("---------------------------\n");

  d = 1.0; // represented as 0x3ff0000000000000
           //                                 ^
           //             The integer will be 0
  memcpy(&i, &d, sizeof(int));
  printf ("%d\n", i);

  printf ("---------------------------\n");

  d = 1.0000000000000002220446049250313080847263336181640625; // represented as 0x3ff0000000000001
                                                              //                                 ^
                                                              //             The integer will be 1
  memcpy(&i, &d, sizeof(int));
  printf ("%d\n", i);

  printf ("---------------------------\n");

  d = 1.000000000000000444089209850062616169452667236328125; // represented as 0x3ff0000000000002
                                                             //                                 ^
                                                             //             The integer will be 2
  memcpy(&i, &d, sizeof(int));
  printf ("%d\n", i);

  printf ("---------------------------\n");

  return 0;
}

输出:

---------------------------
0
---------------------------
1
---------------------------
2
---------------------------

答案 1 :(得分:0)

没有函数声明只有函数定义。因此,编译器无法告诉它应该调用哪个函数。因为&#34;较新的&#34;你的编译器应该警告你的标准。

其他人指出的#define __func_也不应该使用,因为以下划线开头的定义会保留给预处理器。

首先在头文件中声明函数(告诉编译器如何调用函数):

#ifndef FUNC_H_
#define FUNC_H_

double get_number(double n);

#endif /* FUNC_H_ */

然后在你的.c文件中定义它(告诉编译器函数做什么)

#include "func.h" // include the function declaration    

double get_number(double n)
{
  return n;
}

现在使用它

#include <stdio.h>
#include "func.h" // again include the function declaration

int main()
{
  printf("%f\n", get_number(1.0)); // use the function
}

最佳做法是在编译时启用所有警告,如果您想绝对确定,您的程序没有任何问题,也将编译器警告视为错误

gcc -std=c11 -Wall -Wextra -Werror -pedantic -o myProgram main.c func.c

explained: 
-Wall   // enable all warnings
-Wextra // REALY enable all warnings
-Werror // treat all warnings as errors (so the program won't compile if there is any mistake)

-std=c11 // use the newest standard