...的多个定义(链接器错误?)

Multiple definitions of ... (linker error?)

我的代码中出现某种 compiler/linker 错误,很可能与预处理器相关。错误消息显示为 "multiple definitions of x",其中 x 是我的 lib.c 文件中的 4 个函数中的任何一个。我使用的 compiler/linker 是与 code:blocks

一起打包的 GNU GCC 编译器

我已经尝试更改 #includes 的顺序但没有成功,让我相信这是一个链接器错误而不是编译器错误的事实是,如果我故意犯了语法错误,编译器会发现并中止而不给出错误消息。

所有 help/advice/criticism 感谢,提前致谢!

这里是 main.c 文件:

#include <stdlib.h>
#include "lib.c"

int main()
{
getGradeAverage();
return EXIT_SUCCESS;
}

和lib.c:

#include "defs.h"

void getUserName ()
{
printf ("please enter the your name:");
studentRecord sr;
scanf("%40[^\n]%*c",&sr.studentName);
}

void getCourse (index)
{
printf("please enter the name of course 1:");
courseRecord cr1;
scanf("%40[^\n]%*c",&cr1.courseName);
do{
    printf("please enter a grade for course 1:");
        if ((scanf("%i",&cr1.grade))>-2)
        {
            printf("the grade you entered is not on the scale. please try again:");
            fflush(stdin);
            continue;
        }
    } while(true);
printf("please enter the name of course 2:");
courseRecord cr2;
scanf("%40[^\n]%*c",&cr2.courseName);
    do{
    printf("please enter a grade for course 1:");
        if ((scanf("%i",&cr2.grade))>-2)
        {
            printf("the grade you entered is not on the scale. please try again:");
            fflush(stdin);
            continue;
        }
    } while(true);

}

void GPAPrint ()
{
    int GPA;
    studentRecord sr;
    courseRecord cr1;
    courseRecord cr2;
    printf("Student name: %s\n",&sr.studentName);

}

void getGradeAverage ()
{
    int index=1;
    getUserName();
    getCourse(index);
    GPAPrint();
    return (0);

}

defs.h 文件也与此处相关,因为它包含大部分#includes 和结构。

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
#include <string.h>
#define MAX_LENGTH 40

typedef struct courseRecord
{
char courseName [MAX_LENGTH+1];
int grade;
}courseRecord;

typedef struct studentRecord
{
char studentName [MAX_LENGTH+1];
char courseName[2];
}studentRecord;

据推测,您已将 lib.c 包含在您的构建中,并且 #include 将其包含在 main.c 中。这导致编译的 objects(比如,lib.omain.o)每个都有函数的定义。链接器发现了这一点(因为它检查所有 object 文件,而编译器一次只生成一个,因此无法检测到两个或多个 objects 文件多次定义某些内容的情况)并抱怨关于多重定义。

作为准则,永远不要 #include .c 文件。

相反,将函数的声明(又名原型)放在 header 文件中(比如 lib.h

 #ifndef LIB_H_INCLUDED
 #define LIB_H_INCLUDED

 #include "defs.h"

 void getUserName();
 void getCourse (index);

  // etc

 #endif

#include 在每个 .c 文件中需要使用这些函数。这提供了足够的信息,因此编译器可以检查您是否正确调用了函数。然后将函数定义(又名它们的实现)放在 lib.c 中。 lib.c 还需要 #include "lib.h",因此(除其他事项外)编译器可以检查 header 中的函数声明是否与定义匹配。

我还在 header 中放置了包含守卫。我会把它作为练习留给你 google 找出原因。