代码之家  ›  专栏  ›  技术社区  ›  Jordi

如何防止在C中使用多个定义?

  •  34
  • Jordi  · 技术社区  · 15 年前

    我是一名C新手,我只是想用Code::Blocks编写一个控制台应用程序。以下是(简化)代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include "test.c" // include not necessary for error in Code::Blocks
    
    int main()
    {
        //t = test(); // calling of method also not necessary
        return 0;
    }
    

    测试c:

    void test() {}
    

    当我尝试构建此程序时,会出现以下错误:

    *path*\test.c|1|multiple definition of `_ test'|
    obj\Debug\main.o:*path*\test.c|1|first defined here|
    

    我已经排除了这个错误是由于与其他名为test或test.c的函数或文件的命名冲突造成的。请注意,多重定义和第一个定义位于同一文件中的同一行。

    有人知道这是什么原因吗?我能做些什么?谢谢

    7 回复  |  直到 15 年前
        1
  •  100
  •   mouviciel    15 年前

    您实际上编译了 test.c 两次:

    • 第一次编译时 测试c 它本身
    • 第二次编译时 main.c 来源

    你的生活需要什么 main.c 为了使用 test() 函数是一个简单的声明,而不是它的定义。这是通过包括 test.h 包含以下内容的头文件:

    void test(void);
    

    这会通知编译器存在具有输入参数和返回类型的函数。此函数的作用(内部所有内容) { } 测试c 文件

    #include "test.c" #include "test.h" .

    最后一点:随着您的程序变得更加复杂,您将面临头文件可能包含多次的情况。为了防止出现这种情况,标头源有时会被特定的宏定义所包围,例如:

    #ifndef TEST_H_INCLUDED
    #define TEST_H_INCLUDED
    
    void test(void);
    
    #endif
    
        2
  •  27
  •   paxdiablo    15 年前

    下划线由编译器放在那里,并由链接器使用。基本路径是:

    main.c
    test.h ---> [compiler] ---> main.o --+
                                         |
    test.c ---> [compiler] ---> test.o --+--> [linker] ---> main.exe
    

    因此,主程序应包含测试模块的头文件,该头文件应仅包含声明,例如函数原型:

    void test(void);
    

    通过将test.c包含到main.c中,可以在main.o中定义test()函数。假设您正在链接main.o和test.o,两者都包含函数test()。

        3
  •  11
  •   BenMorel Manish Pradhan    11 年前

    .c文件。我想你想要一个头球(

    错误是由测试函数的多个定义(一个在test.c中,另一个在main.c中)引起的

        4
  •  6
  •   eboix Raj Adroit    12 年前

    我也有类似的问题,我用下面的方法解决了它。

    解决方法如下:

    函数原型声明和全局变量应该在test.h文件中,并且不能在头文件中初始化全局变量。

    test.c文件中全局变量的函数定义和使用

    若您在标题中初始化全局变量,它将出现以下错误

    “测试”的多重定义| 路径 \测试c | 1 |首先在此处定义|

        5
  •  4
  •   dirkgently    15 年前

    包括实现文件( test.c test 有两个定义--一个在的目标代码中 main.c 一次 测试c ,这会使您违反ODR。您需要创建一个头文件,其中包含 测验 并将其包含在 main.c :

    /* test.h */
    #ifndef TEST_H
    #define TEST_H
    void test(); /* declaration */
    #endif /* TEST_H */
    
        6
  •  4
  •   Community pid    4 年前

    如果已将test.c添加到Code::Blocks项目中,则该定义将被查看两次—一次通过#include,一次由链接器查看。您需要:

    • 删除#include“test.c”
    • 创建包含以下声明的文件test.h: 无效试验();
        7
  •  4
  •   cwap    15 年前

    如果您使用的是Visual Studio,您还可以在headerfile的顶部执行“#pragma once”,以实现与“#ifndef…”包装相同的功能。其他一些编译器可能也支持它。。

    祝你好运

        8
  •  0
  •   Louis    3 年前

    我在头文件中定义了一个函数,它一直抛出这个错误。( 我知道这不是正确的方法,但我想我会很快用这种方法进行测试。 )

    只有 在头文件中放入声明,在cpp文件中放入定义。

    原因是头文件没有编译,它们只提供定义。

    推荐文章