我正在学习C,但我对使用Java等高级编程语言有很长的经验。
我正在阅读有关头文件的内容,所以我正在玩它们,但是我注意到我可以从另一个文件调用一个函数而不用#including它(它在同一个目录中),这怎么可能? 是make文件,以这种方式配置的链接器还是什么?
我们有两个文件
main.c
add.c
main.c从add add.c调用函数add(int x,int y)
,但是在#including add.c之前我错误地编译了它并且它工作了!更令人困惑的是,当我#include add.c时,它在函数add上给出了多重定义错误
答案 0 :(得分:81)
答案 1 :(得分:4)
问题是您不应该#include
.c文件。
要在另一个文件中使用某个函数,您需要声明它。通常,每个.c文件(main.c除外)都有一个关联的头文件(.h),它正确地声明了.c文件中定义的所有函数。您可以根据需要声明(只要所有声明都相同),但只能有一个定义。
当#include "add.c"
表示add.c的文本包含在main.c中时,会发生什么?给出main.ca 定义(以及作为副作用的声明) )add
。然后,当您自己编译add.c时,会创建 add
的另一个定义。因此,函数有两个定义,编译器因为不知道使用哪一个而吓坏了。
如果将其更改为#include "add.h"
,其中add.h看起来像这样:
#ifndef ADD_H
#define ADD_H
extern int add(int x, int y);
#endif /* ADD_H - Google "include guard" for more info about this trickery */
然后main.c声明为add
并且可以使用该函数,但add
的定义仅在add.c文件中非常牢固,并且所以它只存在一次,所以它会正确编译。
答案 2 :(得分:2)
以下是从不同的c程序调用函数的简单示例
让我将主程序命名为main.c,将函数命名为function.c的函数。我正在创建名为function.h的头文件
的main.c
#include"function.h"
int main()
{
int a = sum(1,2);
return a;
}
function.c
int function(int a,int b)
{
return a+b;
}
function.h
int function(int,int);
要编译,请使用下面给出的命令
g ++ main.c function.c -o main
这里详细解释。在主程序中,我调用了函数来求和2个数。 主程序中的值1和2通过头函数h提供给function.c中的函数,头函数h保存访问点或函数c的桥。
有关详细信息,请查看以下链接
http://www.cplusplus.com/forum/beginner/34691/
https://social.msdn.microsoft.com/Forums/en-US/4ea70f43-a0d5-43f8-8e24-78e90f208110/calling-a-function-in-a-file-from-another-file?forum = winembplatdev
添加print语句来检查结果或使用echo $?在执行文件main
之后答案 3 :(得分:1)
您可以调用它,因为在C中进行调用不需要声明。但是返回类型是未知的,因此默认为int
。这可能部分是由于C中的默认调用约定,以及类型的默认提升至少为int
精度。
如果包含定义要调用的函数的头文件,编译器可以检查对函数的调用是否具有正确的参数数量和类型。
如果包含函数定义,除非您使用static
指定其存储,否则将导出它们。由于您还在编译和链接add.c
,因此您无法添加此项,因此您的目标文件都不会导出add
。
如果您想简单地包含所有功能,最好将其定义放入标题中,并在其上添加存储说明符。