下面的代码尝试一个简单的操作,将float-point 1.0
与函数get_number
的返回值进行比较。
我只定义了get_number
函数而没有声明,因此函数get_number
的返回类型是int
而不是double
,所以最终输出是{{1不是0
。
但是如果我在1
文件中声明了函数get_number
,它就会被罚款。
请提前帮助或尝试提供一些解释它的想法。
func.h
#include <stdlib.h>
#include "func.h"
int main() {
printf ("%d\n", 1.0 == get_number(1.0));
return 0;
}
double get_number(double n) {
return n;
}
输出:
0
注意:
平台:Linux
gcc版本:4.8.5
答案 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