Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 链接中的多重定义_C_Linker - Fatal编程技术网

C 链接中的多重定义

C 链接中的多重定义,c,linker,C,Linker,我是链接的初学者,假设我有两个.c文件 file1.c是 #include <stdio.h> #include "file2.c" int main(int argc, char *argv[]) { int a = function2(); printf("%d",a); return 0; } 当我编译时,出现了一个链接器错误,它是function2的多个定义,但我在file2.c中只定义了一次function?您应该创建一个头文件file2.h

我是链接的初学者,假设我有两个.c文件

file1.c是

#include <stdio.h>
#include "file2.c"


int main(int argc, char *argv[]) 
{
    int a = function2();
    printf("%d",a);
    return 0;
}

当我编译时,出现了一个链接器错误,它是function2的多个定义,但我在file2.c中只定义了一次function?

您应该创建一个头文件file2.h,其中包含:

int function2(void);
以及一个文件file2.c,其函数为:file2.h,其函数为:

#include "file2.h"

int function2(void) 
{ 
    return 2018;
    ...
} 
然后,在主标题中,必须包含标题和:

#include "file2.h"

请注意,所有这些文件应位于同一文件夹中,以避免任何链接问题

您应创建一个头文件file2.h,其中包含:

int function2(void);
以及一个文件file2.c,其函数为:file2.h,其函数为:

#include "file2.h"

int function2(void) 
{ 
    return 2018;
    ...
} 
然后,在主标题中,必须包含标题和:

#include "file2.h"

请注意,所有这些文件都应位于同一文件夹中,以避免出现任何链接问题

#include <stdio.h>
#include "file2.h"

int main(int argc, char *argv[]) 
{
    int a = function2();
    printf("%d",a);
    return 0;
}
而file2.c是

int function2() 
{ 
    return 2018;
}
#include "file2.h"

int function2(void) 
{ 
    return 2018;
}

然后将其链接在一起。

尝试以下方法:

#include <stdio.h>
#include "file2.h"

int main(int argc, char *argv[]) 
{
    int a = function2();
    printf("%d",a);
    return 0;
}
而file2.c是

int function2() 
{ 
    return 2018;
}
#include "file2.h"

int function2(void) 
{ 
    return 2018;
}
然后将其链接在一起。

语句include file2.c有效地将file2.c的内容合并到file1.c中。然后编译file1.c,就好像它包含:

int function2() 
{ 
    return 2018;
}
int function2();
这些行定义了函数2;它们告诉编译器“这里是function2,为它创建代码。”因为这些行实际上同时出现在file1.c和file2.c中,所以您的程序有function2的两个副本

相反,您应该创建包含以下内容的file2.h:

int function2() 
{ 
    return 2018;
}
int function2();
该行告诉编译器“存在一个名为function2的函数,但它的定义在其他地方。”

然后,在file1.c中,使用include file2.h而不是include file2.c。这将告诉编译器,在编译file1.c时,编译对function2的调用需要知道什么。编译器将有它需要的声明,但它没有定义,这在file1.c中是不需要的

另外,在file2.c中,插入include file2.h。然后file2.c将包含file2.h中function2的声明和file2.c中实际行中function2的定义。这样做的目的是,编译器在编译file2.c时可以同时看到声明和定义,因此如果存在导致它们不兼容的印刷错误,它可以向您发出警告

此外,在C中,应该使用int-function2void而不是int-function2。出于历史原因,后者未指定参数。使用void告诉编译器没有参数。

语句include file2.c有效地将file2.c的内容合并到file1.c中。然后编译file1.c,就好像它包含:

int function2() 
{ 
    return 2018;
}
int function2();
这些行定义了函数2;它们告诉编译器“这里是function2,为它创建代码。”因为这些行实际上同时出现在file1.c和file2.c中,所以您的程序有function2的两个副本

相反,您应该创建包含以下内容的file2.h:

int function2() 
{ 
    return 2018;
}
int function2();
该行告诉编译器“存在一个名为function2的函数,但它的定义在其他地方。”

然后,在file1.c中,使用include file2.h而不是include file2.c。这将告诉编译器,在编译file1.c时,编译对function2的调用需要知道什么。编译器将有它需要的声明,但它没有定义,这在file1.c中是不需要的

另外,在file2.c中,插入include file2.h。然后file2.c将包含file2.h中function2的声明和file2.c中实际行中function2的定义。这样做的目的是,编译器在编译file2.c时可以同时看到声明和定义,因此如果存在导致它们不兼容的印刷错误,它可以向您发出警告


此外,在C中,应该使用int-function2void而不是int-function2。出于历史原因,后者未指定参数。使用void告诉编译器没有参数。

include file2.c是一种完全错误的方法,函数定义在源文件中实现。头文件中的函数声明。包含头文件,使用源文件生成。如果包含file2.c,则不需要单独编译file2.c并将其与file1.o链接-file2.o中的信息已包含在file1.o中。更正常的是在file2.c和file1.c中都包含file2.h,然后需要编译并将两个源文件链接到一个可执行文件中。include file2.c是一种完全错误的方法,在源文件中实现函数定义。头文件中的函数声明。包含头文件,使用源文件生成。如果包含file2.c,则不需要单独编译file2.c并将其与file1.o链接-file2.o中的信息已包含在file1.o中。更正常的是在file2.c和file1.c中都包含file2.h,然后需要编译并将两个源文件链接到一个可执行文件中。我个人的意见是:应该从file2.h中删除extern,这没有错,但没有错necessary@Jabberwocky:不是每个人都会同意你的观点-例如,我不知道。@JonathanLeffler你能详细说明一下吗
?@Jabberwocky:我更喜欢看extern int function2voidl;在标题中。我承认有些人不喜欢看外景;我更喜欢看extern,如果只是为了与那些有时必须在标题中声明的全局变量的extern声明对称,其中extern是至关重要的。@Jabberwocky:附加到函数声明中,关键字extern是可选的-是。我个人的观点是:你应该从文件2.h中删除extern,这没有错,但没有错necessary@Jabberwocky:不是每个人都会同意你的观点-例如,我不知道。@JonathanLeffler你能详细说明一下吗?@Jabberwocky:我更喜欢看extern int function2voidl;在标题中。我承认有些人不喜欢看外景;我更喜欢看extern,如果只是为了与那些有时必须在标题中声明的全局变量的extern声明对称,其中extern是至关重要的。@Jabberwocky:附加到函数声明中,关键字extern是可选的-是。在我看来,这一点更清楚,但并不是每个人都同意我的观点,就像每个人都同意你的观点一样。嗨,谢谢你的回答。但是如果我不插入include file2.h。在file2.c中,编译器仍然可以,既然file1.c中已经有include file2.h,为什么我需要插入include file2.h?@amjad:这样编译器就可以在编译file2.c时同时看到声明和定义,以便在出现导致它们不兼容的印刷错误时向您发出警告。您好,你能给我一个印刷错误的例子,使他们不兼容,请?非常感谢你,我可以说int foovid;,而file2.c说的是float foovid….您好,谢谢您的回答。但是如果我不插入include file2.h。在file2.c中,编译器仍然可以,既然file1.c中已经有include file2.h,为什么我需要插入include file2.h?@amjad:这样编译器就可以在编译file2.c时同时看到声明和定义,以便在出现导致它们不兼容的印刷错误时向您发出警告。您好,你能给我一个印刷错误的例子,使他们不兼容,请?非常感谢你,我可以说int foovid;,而file2.c说float foovoid…。