错误:多重定义和首先在这里定义

Fre*_*red 2 c makefile

我尝试包含几乎所有标题组合。尝试使用以下方法编译目标文件:

gcc database.c -c
gcc database.o user_interface.c -o database
Run Code Online (Sandbox Code Playgroud)

结果是:

/tmp/ccWfp2tS.o: In function `addRecord':
user_interface.c:(.text+0x4b9): multiple definition of `addRecord'
database.o:database.c:(.text+0x0): first defined here
/tmp/ccWfp2tS.o: In function `printAllRecords':
user_interface.c:(.text+0x54a): multiple definition of `printAllRecords'
database.o:database.c:(.text+0x1a): first defined here
/tmp/ccWfp2tS.o: In function `findRecord':
user_interface.c:(.text+0x590): multiple definition of `findRecord'
database.o:database.c:(.text+0x24): first defined here
/tmp/ccWfp2tS.o: In function `deleteRecord':
user_interface.c:(.text+0x5ed): multiple definition of `deleteRecord'
database.o:database.c:(.text+0x36): first defined here
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

用户界面.c

#include "record.h"

int debugmode; 

int main(int argc, char *argv[])
{ 
    // my code here
}
    // other functions: AddRecord, printallRecords,...
Run Code Online (Sandbox Code Playgroud)

数据库.h

#include "record.h"

int addRecord (struct record **, int, char [ ],char [ ]);
void printAllRecords(struct record *);
int findRecord (struct record *, int);
int deleteRecord(struct record **, int);
Run Code Online (Sandbox Code Playgroud)

数据库.c

#include "database.h"

extern int debugmode; 

int addRecord(struct record ** start, int account, char name[], char address[])
{
    /*my code here*/
    return 0;
}
/*other functions...*/
Run Code Online (Sandbox Code Playgroud)

记录.h

struct record
{
    int                accountno;
    char               name[25];
    char               address[80];
    struct record*     next;
};
Run Code Online (Sandbox Code Playgroud)

Mad*_*ist 6

你似乎遇到了很多麻烦,因为你在杂草丛中,向墙上扔东西。但如果退一步,从更高的层面来看,其实并没有那么难。

这里感兴趣的概念是声明定义。不幸的是他们的名字如此相似:很容易让他们混淆。

可以将定义想象为您的房屋,将声明想象为您房屋的地址。你只有一间房子,但你可以将你的地址分发给很多不同的人。您的地址告诉人们如何到达您的家,但它实际上并不是您的家。

类似地,在C中,函数的定义是函数的实际实现,函数的声明描述了如何调用该函数。

声明如下所示:

void printAllRecords(struct record *);
Run Code Online (Sandbox Code Playgroud)

(注意,没有函数体,只是调用它的方式)并且定义如下:

void printAllRecords(struct record *record)
{
    ...do some stuff...
}
Run Code Online (Sandbox Code Playgroud)

(注意,现在你有了函数的主体)

通常将声明放在头文件中。然后任何想要调用您的函数的人都会使用#include该头文件,以便他们知道调用它的正确方法。

但是您不想#include定义函数(例如,通过ing 源文件),因为这意味着您有同一函数的两个实现,而这是不可能的,就像您的房子不能有两个一样#include

所以,简而言之:

  • 将函数的定义放入源文件中
  • 将函数声明放入头文件中
  • 您应该将#include包含声明的头文件放在包含定义的源文件中,这样如果它们不匹配,编译器就会抱怨
  • 最后,如果您想从其他源文件调用该函数,则#include头文件也包含该源文件中的声明

在您的情况下,中定义的所有函数都database.c应该在 中具有声明database.h,然后任何其他源文件(例如user_interface.c)应该#include "database.h"看到这些声明。