11

我想在另一个中包含一个 .c 文件。有可能吗?如果我在 .c 文件中包含头文件,它会很好用,但如果我在另一个 .c 文件中包含 .c 文件,它就不会很好用。
我正在使用 Visual Studio,但出现以下错误:

main.obj : error LNK2005: _sayHello already defined in sayHello.obj  
/* main.c  */
#include "sayHello.c"

int main()
{
    return 0;
}  
/* sayHello.c */

#include <stdio.h>

void sayHello()
{
    printf("Hello World");
}

我不知道这个错误可能意味着什么。是时候询问更高级的 C 编码器了。:)

4

8 回答 8

28

我想在另一个中包含一个 .c 文件。

不,你没有。你真的,真的没有。不要在这条路上采取任何步骤;它只会以痛苦和苦难告终。即使对于像您的示例这样的琐碎程序,这也是不好的做法,对于任何真正复杂的程序来说更是如此。一个文件中的微不足道的单行更改将需要您重建该文件以及包含它的任何内容,这是浪费时间。您失去了控制对数据和功能的访问的能力;包含的 .c 文件中的所有内容对包含文件都是可见的,甚至是声明的函数和文件范围变量static。如果您最终包含一个 .c 文件,该文件包含另一个 .c 文件,该文件包含另一个 .c 文件und so weiter,您可能会以编译器无法处理的翻译单元结束。

单独的编译和链接是一件明确的好事。您应该在 .c 文件中包含的唯一文件是描述接口(类型定义、函数原型声明、宏定义、外部声明)的头文件,而不是实现。

于 2012-05-04T14:13:38.080 回答
11

它可以工作,但是您需要小心构建程序的方式。此外,正如人们在评论中指出的那样,这通常被认为是一个坏主意。这是出乎意料的,它会产生这样的问题。好处很少,尤其是对于看起来微不足道的程序。您可能应该完全重新考虑这种方法。

在做了这样的事情之后,你应该只 compile main.c,而不是试图将它与sayHello.c你似乎正在做的 compile 的结果联系起来。

您可能需要告诉 Visual Studio从 build 中排除后一个文件

于 2012-05-04T11:37:02.890 回答
4

是的,任何“.c”文件都可以包含在另一个程序中。作为一个包含“.h”文件的程序,如“stdio.h”。之后我们可以调用那些写入这个外部文件的函数。

测试.c::

#include<stdio.h>
#include<conio.h>
void xprint()
{
    printf("Hello World!");
}

主.c::

#include "test.c"
void main()
{
   xprint();
   getch();
}

输出:: 你好世界!

于 2018-06-03T14:45:12.880 回答
2

这是一个链接器错误。将所有 .c 文件编译为 .obj 文件(由编译器完成)后,链接器将它们“合并”在一起以生成 dll/exe。链接器发现两个对象声明了相同的函数(这显然是不允许的)。在这种情况下,您可能希望链接器只处理 main.obj 而不是 sayhello.obj(因为它的代码已经包含在 main.obj 中)。

这是因为在 main.obj 中,由于包含,您还将拥有 sayHello() 函数!

于 2012-05-04T11:39:29.357 回答
0

说你好.h

#include <stdio.h>
void sayHello(void);

主程序

#include "sayHello.h"

int main()
{
    sayHello();
    return 0;
}  
于 2012-05-04T13:06:10.237 回答
0

你可能定义了两次这个函数

void sayHello()
{
printf("Hello World");
}

一个在您当前的文件中,一个在 sayhello.c 中

您必须删除一个定义。

于 2012-05-04T11:36:49.740 回答
0

问题似乎是sayHello.c被编译成一个名为 的目标文件sayHello.obj,并且main.c(还包括来自 的所有源文本sayHello.c)被编译成main.obj,因此这两个.obj文件都staticsayHello.c.

然后所有的目标文件应该被“链接”在一起以产生最终的可执行程序文件,但是当任何外部符号出现不止一次时,链接就会中断。

如果您发现自己处于这种情况,您需要停止链接sayHello.objmain.obj(然后您可能根本不想自己编译sayHello.c成它自己的目标文件)。

如果您手动控制构建的每个步骤(就像您在使用编译器的 CLI 时可能那样),这通常只是从链接器或编译器的调用中排除该目标文件的问题。

由于您使用的是 Visual Studio,它可能会为您做出一堆假设,例如“每个 .c 文件都应该编译成自己的目标文件,并且所有这些目标文件都应该链接在一起”,您必须找到一种方法规避或禁用此假设sayHello.c

一种简单且有点惯用的解决方案可能是将重命名sayHello.csayHello.c.inc.

于 2021-03-01T03:05:02.620 回答
0
//THIS IS THE MAIN FILE//
#include "test.c"
int main()
{
    multi(10);
}


//THIS IS THE TEST FILE//
#include<stdio.h>
void multi(int a)
{
    printf("%d",a*2);
}

注意事项:

  1. 在这里你需要运行包含“main()”函数的程序。
  2. 您可以避免主函数中的“stdio.h”头文件。因为,您包含的文件已经包含“stdio.h”头文件。
  3. 您必须从“主”文件中调用该函数。
  4. 包含文件应该是“file_name.c”而不是“file_name.h”。因为通常我们对头文件使用 .h 扩展名。由于我们包含另一个程序文件而不是头文件,因此我们必须使用 .c。否则它会给你致命错误并且编译被终止。
于 2021-05-07T05:41:07.043 回答