头文件定义结构体,fatal error LNK1169: 找到一个或多个多重定义的符号

五岳凌峰 2016-03-16 08:16:20
正在学习多文件编译,工程包括1个头文件(stuscore.h)、3个源文件(main.cpp、a1.cpp、a2.cpp)。其代码分别如下

stuscore.h:
#ifndef _STUDENTSCORE_H_
#define _STUDENTSCORE_H_

#include <stdio.h>
#include <stdlib.h>
#include <iostream>

struct student_score
{
char name[10];
int num;
int China;
int Math;
int English;
}score[100];

void save(char*name,int n);
void show(char*name,int n);

#endif


main.cpp:
#include "stuscore.h"

int main()
{
int i,n;
char filename[50];
printf("how many students in your class?\n");
scanf("%d",&n);
printf("please input filename:\n");
scanf("%s",filename);
printf("please input name,number,China,math,English:\n");
for(i=0;i<n;i++)
{
printf("NO%d",i+1);
scanf("%s%d%d%d%d",score[i].name,&score[i].num,&score[i].China,&score[i].Math,&score[i].English);
save(filename,n);
}
show(filename,n);
system("pause");
}


a1.cpp:
#include "stuscore.h"

void save(char*name,int n)
{
FILE *fp;
int i;
if ((fp=fopen(name,"wb"))==NULL)
{
printf("cannot open file\n");
exit(0);
}
for(i=0;i<n;i++)
if(fwrite(&score[i],sizeof(struct student_score),1,fp)!=1)
printf("file write error\n");
fclose(fp);
}


a2.cpp:
#include "stuscore.h"

void show(char*name,int n)
{
int i;
FILE *fp;
if ((fp=fopen(name,"rb"))==NULL)
{
printf("cannot open file\n");
exit(0);
}
for (i=0;i<n;i++)
{
fread(&score[i],sizeof(struct student_score),1,fp);
printf("%-10s%4d%4d%4d%4d\n",score[i].name,score[i].num,score[i].China,score[i].Math,score[i].English);
}
}


运行后报错:
1>a1.obj : error LNK2005: "struct student_score * score" (?score@@3PAUstudent_score@@A) 已经在 main.obj 中定义
1>a2.obj : error LNK2005: "struct student_score * score" (?score@@3PAUstudent_score@@A) 已经在 main.obj 中定义
1>G:\VS2010\mywork\example7\Debug\e170.exe : fatal error LNK1169: 找到一个或多个多重定义的符号

网上搜了很多相似问题,但回答不能完全对应出错情况。希望师兄解答下
...全文
492 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
gh_99 2016-03-16
  • 打赏
  • 举报
回复
7# 就行了.
五岳凌峰 2016-03-16
  • 打赏
  • 举报
回复
引用 8 楼 qq423399099 的回复:
[quote=引用 6 楼 u012911202 的回复:] [quote=引用 1 楼 qq423399099 的回复:] LZ的这个错误是典型的链接错误,#ifndef 加在头文件重是为了保证类的头文件在一个.cpp文件中被多次引用后会不会出现重复定义的问题,注意,只是防止在一个.cpp文件中被多次引用 如果是C++,可以对头文件的函数定义加inline或者static表明函数是在线或者静态的,这样编译器就可以自行解决重复定义的问题。 如果是C,则只能通过头文件函数定义加static来表明函数为静态,这样连接器不会报错。 正确的做法应该是只在头文件中声明,而真正的定义放到源文件中,这样不管哪个源文件包含了头文件,都不会有问题,因为定义的地方只有一个,链接的时候会找到的。
谢谢师兄回复,有问题想继续请教: 问题1,头文件中只声明不定义,学习过这点。师兄强调的:#ifndef只是防止在一个.cpp中被多次引用,不是很明白。拿main.cpp来说,我在里面不同位置写了两次#include "stuscore.h",#ifndef的作用就显出来了?可以这理解不? 问题2,C++加inline或static,C加static,针对我这个具体工程,适用吗?需要的话,具体加在哪个位置? [/quote] 第一个可以这么理解 第二个的话,感觉并不不太适用,全局静态的只能在一个文件里用,其他文件访问不到,就算名字相同也是不同的变量[/quote]
gh_99 2016-03-16
  • 打赏
  • 举报
回复
引用 5 楼 u012911202 的回复:
[quote=引用 3 楼 github_27756899 的回复:] stuscore.h:

struct student_score
{
    char name[10];
    int num;
    int China;
    int Math;
    int English;
}score[100];
//改为如下:
struct student_score
{
    char name[10];
    int num;
    int China;
    int Math;
    int English;
};
main.cpp:

#include "stuscore.h"
 
int main()
{
    int i,n;
    char filename[50];
//添加 struct student_score score[100];
a1.cpp :

#include "stuscore.h"
 
void save(char*name,int n)
{
    FILE *fp;
    int i;
//添加 extern struct student_score score[100];
a2.cpp :

#include "stuscore.h"
 
void show(char*name,int n)
{
    int i;
    FILE *fp;
//添加 extern struct student_score score[100];
试试
谢谢师兄的具体修改。改过后,出现新问题: 1>a1.obj : error LNK2001: 无法解析的外部符号 "struct student_score * score" (?score@@3PAUstudent_score@@A) 1>a2.obj : error LNK2019: 无法解析的外部符号 "struct student_score * score" (?score@@3PAUstudent_score@@A),该符号在函数 "void __cdecl show(char *,int)" (?show@@YAXPADH@Z) 中被引用 1>G:\VS2010\mywork\example7\Debug\e170.exe : fatal error LNK1120: 1 个无法解析的外部命令 这个错误也常见,网上解答较多,只是自己不能对应上。。。[/quote]

#include "stuscore.h"

  //添加 struct student_score score[100]; 
int main()
{
    int i,n;
    char filename[50];
a1.cpp :

#include "stuscore.h"
 //添加 extern struct student_score score[100];
void save(char*name,int n)
{
    FILE *fp;
    int i;

a2.cpp :

#include "stuscore.h"
 //添加 extern struct student_score score[100];
void show(char*name,int n)
{
    int i;
    FILE *fp;

五岳凌峰 2016-03-16
  • 打赏
  • 举报
回复
引用 7 楼 cutmelon 的回复:
stuscore.h:
#ifndef _STUDENTSCORE_H_
#define _STUDENTSCORE_H_

#include <stdio.h>
#include <stdlib.h>
#include <iostream>

struct student_score
{
	char name[10];
	int num;
	int China;
	int Math;
	int English;
};

extern struct student_score score[100];

void save(char*name,int n);
void show(char*name,int n);

#endif 
main.cpp:
#include "stuscore.h"

student_score score[100];

int main()
{
	int i,n;
	char filename[50];
	printf("how many students in your class?\n");
	scanf("%d",&n);
	printf("please input filename:\n");
	scanf("%s",filename);
	printf("please input name,number,China,math,English:\n");
	for(i=0;i<n;i++)
	{
		printf("NO%d",i+1);
		scanf("%s%d%d%d%d",score[i].name,&score[i].num,&score[i].China,&score[i].Math,&score[i].English);
		save(filename,n);
	}
	show(filename,n);
	system("pause");
}
a1.cpp:
#include "stuscore.h"

void save(char*name,int n)
{
	FILE *fp;
	int i;
	if ((fp=fopen(name,"wb"))==NULL)
	{
		printf("cannot open file\n");
		exit(0);
	}
	for(i=0;i<n;i++)
		if(fwrite(&score[i],sizeof(struct student_score),1,fp)!=1)
			printf("file write error\n");
	fclose(fp);
}
a2.cpp:
#include "stuscore.h"

void show(char*name,int n)
{
	int i;
	FILE *fp;
	if ((fp=fopen(name,"rb"))==NULL)
	{
		printf("cannot open file\n");
		exit(0);
	}
	for (i=0;i<n;i++)
	{
		fread(&score[i],sizeof(struct student_score),1,fp);
		printf("%-10s%4d%4d%4d%4d\n",score[i].name,score[i].num,score[i].China,score[i].Math,score[i].English);
	}
}
运行成功,谢谢师兄
小灸舞 版主 2016-03-16
  • 打赏
  • 举报
回复
引用 6 楼 u012911202 的回复:
[quote=引用 1 楼 qq423399099 的回复:] LZ的这个错误是典型的链接错误,#ifndef 加在头文件重是为了保证类的头文件在一个.cpp文件中被多次引用后会不会出现重复定义的问题,注意,只是防止在一个.cpp文件中被多次引用 如果是C++,可以对头文件的函数定义加inline或者static表明函数是在线或者静态的,这样编译器就可以自行解决重复定义的问题。 如果是C,则只能通过头文件函数定义加static来表明函数为静态,这样连接器不会报错。 正确的做法应该是只在头文件中声明,而真正的定义放到源文件中,这样不管哪个源文件包含了头文件,都不会有问题,因为定义的地方只有一个,链接的时候会找到的。
谢谢师兄回复,有问题想继续请教: 问题1,头文件中只声明不定义,学习过这点。师兄强调的:#ifndef只是防止在一个.cpp中被多次引用,不是很明白。拿main.cpp来说,我在里面不同位置写了两次#include "stuscore.h",#ifndef的作用就显出来了?可以这理解不? 问题2,C++加inline或static,C加static,针对我这个具体工程,适用吗?需要的话,具体加在哪个位置? [/quote] 第一个可以这么理解 第二个的话,感觉并不不太适用,全局静态的只能在一个文件里用,其他文件访问不到,就算名字相同也是不同的变量
cutmelon 2016-03-16
  • 打赏
  • 举报
回复
stuscore.h:
#ifndef _STUDENTSCORE_H_
#define _STUDENTSCORE_H_

#include <stdio.h>
#include <stdlib.h>
#include <iostream>

struct student_score
{
	char name[10];
	int num;
	int China;
	int Math;
	int English;
};

extern struct student_score score[100];

void save(char*name,int n);
void show(char*name,int n);

#endif 
main.cpp:
#include "stuscore.h"

student_score score[100];

int main()
{
	int i,n;
	char filename[50];
	printf("how many students in your class?\n");
	scanf("%d",&n);
	printf("please input filename:\n");
	scanf("%s",filename);
	printf("please input name,number,China,math,English:\n");
	for(i=0;i<n;i++)
	{
		printf("NO%d",i+1);
		scanf("%s%d%d%d%d",score[i].name,&score[i].num,&score[i].China,&score[i].Math,&score[i].English);
		save(filename,n);
	}
	show(filename,n);
	system("pause");
}
a1.cpp:
#include "stuscore.h"

void save(char*name,int n)
{
	FILE *fp;
	int i;
	if ((fp=fopen(name,"wb"))==NULL)
	{
		printf("cannot open file\n");
		exit(0);
	}
	for(i=0;i<n;i++)
		if(fwrite(&score[i],sizeof(struct student_score),1,fp)!=1)
			printf("file write error\n");
	fclose(fp);
}
a2.cpp:
#include "stuscore.h"

void show(char*name,int n)
{
	int i;
	FILE *fp;
	if ((fp=fopen(name,"rb"))==NULL)
	{
		printf("cannot open file\n");
		exit(0);
	}
	for (i=0;i<n;i++)
	{
		fread(&score[i],sizeof(struct student_score),1,fp);
		printf("%-10s%4d%4d%4d%4d\n",score[i].name,score[i].num,score[i].China,score[i].Math,score[i].English);
	}
}
五岳凌峰 2016-03-16
  • 打赏
  • 举报
回复
引用 1 楼 qq423399099 的回复:
LZ的这个错误是典型的链接错误,#ifndef 加在头文件重是为了保证类的头文件在一个.cpp文件中被多次引用后会不会出现重复定义的问题,注意,只是防止在一个.cpp文件中被多次引用 如果是C++,可以对头文件的函数定义加inline或者static表明函数是在线或者静态的,这样编译器就可以自行解决重复定义的问题。 如果是C,则只能通过头文件函数定义加static来表明函数为静态,这样连接器不会报错。 正确的做法应该是只在头文件中声明,而真正的定义放到源文件中,这样不管哪个源文件包含了头文件,都不会有问题,因为定义的地方只有一个,链接的时候会找到的。
谢谢师兄回复,有问题想继续请教: 问题1,头文件中只声明不定义,学习过这点。师兄强调的:#ifndef只是防止在一个.cpp中被多次引用,不是很明白。拿main.cpp来说,我在里面不同位置写了两次#include "stuscore.h",#ifndef的作用就显出来了?可以这理解不? 问题2,C++加inline或static,C加static,针对我这个具体工程,适用吗?需要的话,具体加在哪个位置?
五岳凌峰 2016-03-16
  • 打赏
  • 举报
回复
引用 3 楼 github_27756899 的回复:
stuscore.h:

struct student_score
{
    char name[10];
    int num;
    int China;
    int Math;
    int English;
}score[100];
//改为如下:
struct student_score
{
    char name[10];
    int num;
    int China;
    int Math;
    int English;
};
main.cpp:

#include "stuscore.h"
 
int main()
{
    int i,n;
    char filename[50];
//添加 struct student_score score[100];
a1.cpp :

#include "stuscore.h"
 
void save(char*name,int n)
{
    FILE *fp;
    int i;
//添加 extern struct student_score score[100];
a2.cpp :

#include "stuscore.h"
 
void show(char*name,int n)
{
    int i;
    FILE *fp;
//添加 extern struct student_score score[100];
试试
谢谢师兄的具体修改。改过后,出现新问题: 1>a1.obj : error LNK2001: 无法解析的外部符号 "struct student_score * score" (?score@@3PAUstudent_score@@A) 1>a2.obj : error LNK2019: 无法解析的外部符号 "struct student_score * score" (?score@@3PAUstudent_score@@A),该符号在函数 "void __cdecl show(char *,int)" (?show@@YAXPADH@Z) 中被引用 1>G:\VS2010\mywork\example7\Debug\e170.exe : fatal error LNK1120: 1 个无法解析的外部命令 这个错误也常见,网上解答较多,只是自己不能对应上。。。
五岳凌峰 2016-03-16
  • 打赏
  • 举报
回复
3楼师兄,谢谢具体修改。改过后,出现新问题: 1>a1.obj : error LNK2001: 无法解析的外部符号 "struct student_score * score" (?score@@3PAUstudent_score@@A) 1>a2.obj : error LNK2019: 无法解析的外部符号 "struct student_score * score" (?score@@3PAUstudent_score@@A),该符号在函数 "void __cdecl show(char *,int)" (?show@@YAXPADH@Z) 中被引用 1>G:\VS2010\mywork\example7\Debug\e170.exe : fatal error LNK1120: 1 个无法解析的外部命令 这个错误也常见,网上解答较多,只是自己不能对应上。。。
gh_99 2016-03-16
  • 打赏
  • 举报
回复
stuscore.h:

struct student_score
{
    char name[10];
    int num;
    int China;
    int Math;
    int English;
}score[100];
//改为如下:
struct student_score
{
    char name[10];
    int num;
    int China;
    int Math;
    int English;
};
main.cpp:

#include "stuscore.h"
 
int main()
{
    int i,n;
    char filename[50];
//添加 struct student_score score[100];
a1.cpp :

#include "stuscore.h"
 
void save(char*name,int n)
{
    FILE *fp;
    int i;
//添加 extern struct student_score score[100];
a2.cpp :

#include "stuscore.h"
 
void show(char*name,int n)
{
    int i;
    FILE *fp;
//添加 extern struct student_score score[100];
试试
小灸舞 版主 2016-03-16
  • 打赏
  • 举报
回复
补充一下
哈哈,有几个错别字见谅
#ifndef 加在头文件中是为了保证类的头文件在一个.cpp文件中被多次引用后不会出现重复定义的问题,注意,只是防止在一个.cpp文件中被多次引用
楼主在头文件中最好不要定义变量(score[100]),变量的定义都放到.cpp文件中
小灸舞 版主 2016-03-16
  • 打赏
  • 举报
回复
LZ的这个错误是典型的链接错误,#ifndef 加在头文件重是为了保证类的头文件在一个.cpp文件中被多次引用后会不会出现重复定义的问题,注意,只是防止在一个.cpp文件中被多次引用
如果是C++,可以对头文件的函数定义加inline或者static表明函数是在线或者静态的,这样编译器就可以自行解决重复定义的问题。
如果是C,则只能通过头文件函数定义加static来表明函数为静态,这样连接器不会报错。
正确的做法应该是只在头文件中声明,而真正的定义放到源文件中,这样不管哪个源文件包含了头文件,都不会有问题,因为定义的地方只有一个,链接的时候会找到的。

70,023

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧