我的代码中出现了某种编译器/链接器错误,很可能与预处理器有关。错误消息读取" x"的多个定义,其中x是我的lib.c文件中的4个函数中的任何一个。我正在使用的编译器/链接器是与代码一起打包的GNU GCC编译器:blocks
我试过改变#includes的顺序没有成功,是什么让我相信这是一个链接器错误而不是编译器错误是因为如果我犯了一个故意的语法错误,编译器会发现并中止而不给出错误信息。
所有帮助/建议/批评表示赞赏,提前谢谢!
这是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;
答案 0 :(得分:1)
据推测,您已在构建中添加了lib.c
,并在#include
中main.c
了它。这会导致编译对象(例如,lib.o
和main.o
)各自具有函数的定义。链接器选择它(因为它检查所有目标文件,而编译器一次生成一个,因此无法检测两个或多个对象文件多次定义某些内容的实例)并抱怨多个定义。
作为指南,永远不要#include
.c
个文件。
相反,将函数的声明(也称为原型)放在头文件中(比如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"
,因此(除其他外)编译器可以检查标头中函数的声明是否与定义匹配。
我还在标题中放置了包含守卫。我会把它作为练习让你去谷歌找出原因。