鱼C论坛

 找回密码
 立即注册
查看: 3513|回复: 7

求助分文件写出现重定义,和一起写,正确编译,这是为什么?

[复制链接]
发表于 2019-5-10 12:18:11 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 qwe6620690 于 2019-5-10 14:35 编辑
  1. /*c1.h*/
  2. #include<string.h>
  3. #include<ctype.h>
  4. #include<malloc.h>        /*malloc()等*/
  5. #include<limits.h>        /*INT_MAX等*/
  6. #include<stdio.h>        /*EOF(= ^Z或F6),NULL*/
  7. #include<stdlib.h>        /*atoi()*/
  8. #include<io.h>                /*eof()*/
  9. #include<math.h>        /*floor(),ceil(),abs()*/
  10. #include<process.h>        /*exit()*/
  11. /* 函数结果状态代码 */
  12. #define TRUE 1
  13. #define FALSE 0
  14. #define OK 1
  15. #define ERROR 0
  16. #define INFEASIBLE -1
  17. //#define OVERFLOW -2

  18. typedef int Status; /*Status是函数的类型,其值是函数结果状态代码*/
  19. typedef int Boolean; /*Boolean是布尔类型,其值是TRUE或FALSE*/
复制代码

  1. //c1-1.h
  2. /*动态分配的顺序存储结构*/
  3. typedef ElemType *Triplet; /*由InttTriplet分配3个元素存储空间*/
  4. /*Triplet类型是ElemType类型的指针,存放ElemType类型的地址*/
复制代码

  1. //bo1-1.c -base operation file
  2. #include"c1.h"

  3. typedef int ElemType;

  4. #include"c1-1.h"

  5. /*基本操作的实现*/
  6. Status InitTriplet(Triplet *T, ElemType v1, ElemType v2, ElemType v3)
  7. {
  8.         if (!(*T = (ElemType *)malloc(3 * sizeof(ElemType))))
  9.                 exit(OVERFLOW);

  10.         (*T)[0] = v1, (*T)[1] = v2, (*T)[2] = v3;

  11.         return OK;
  12. }
复制代码

  1. //main.c -test function main file
  2. #include"bo1-1.c"

  3. int main(void)
  4. {
  5.         Triplet T = NULL;
  6.         ElemType m = 0;
  7.         Status i;

  8.         i = InitTriplet(&T, 7, 8, 9);

  9.         printf("%d\n", i);

  10.         system("pause");
  11.         return 0;
  12. }
复制代码

  1. 输出结果:
  2. 1>bo1-1.c
  3. 1>main1-1.c
  4. 1>正在生成代码...
  5. 1>main1-1.obj : error LNK2005: _InitTriplet 已经在 bo1-1.obj 中定义
  6. 1>E:\source code\data structure and algorithm\source code\CH1\Debug\CH1.exe : fatal error LNK1169: 找到一个或多个多重定义的符号
  7. 1>已完成生成项目“CH1.vcxproj”的操作 - 失败。
  8. ========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
复制代码


上面四个文件合一个文件正常编译,分开为什么出现重定义错误? 先谢过各位了!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2019-5-10 13:11:53 | 显示全部楼层
把两个.h文件都包含,应该就可以了。
我理解的是:程序编译有顺序的。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-5-10 13:47:25 | 显示全部楼层
wwhywhy 发表于 2019-5-10 13:11
把两个.h文件都包含,应该就可以了。
我理解的是:程序编译有顺序的。

嗯,编译都是从上往下,对上面的文件,从上往下,从main1-1.c开始,
main1-1.c文件里用包含命令包含了#include"bo1-1.c"
而bo1-1.c文件里包含了
#include"c1.h"

typedef int ElemType;

#include"c1-1.h"
那么编译过程顺序应该没错啊.
先把库函数文件内容代替到c1.h文件里的包含文件位置处
再把c1.h文件内容代替到bo1-1.c 最前面,
再把c1-1.h内容代替到typedef int ElemType;之后
紧接着把bo1-1.c文件内容代替到main1-1.c
这时候预处理就完成,最后进行逐条语句的翻译
其中 InitTriplet只出现了两个地方, 一个在主调函数外部前面(定义函数),一个是主调函数里(调用此函数).
而C语言中,被调函数在主调函数前定义,可以不需要用函数原型声明了!没出现重定义.编译为什么还提示重定义错误呢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-10 13:49:37 | 显示全部楼层
本帖最后由 wwhywhy 于 2019-5-10 13:52 编辑

编译顺序不能简单的理解成从上往下。
我没有对你的代码编译。不过我们做项目都是尽量多包含。
如果怕重复引用。可以加定义宏
#if not define >>>
#define >>>

这样就不会重复包含了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-5-10 13:58:46 | 显示全部楼层
wwhywhy 发表于 2019-5-10 13:49
编译顺序不能简单的理解成从上往下。
我没有对你的代码编译。不过我们做项目都是尽量多包含。
如果怕重复 ...

额,好像忘了一细节了,编译器编译是以文件为单位进行编译,在bo1-1.c编译过一次了,然后又给包含进main1-1.c文件里,重新编译一次,这样就出现了重编译问题,输出结果就成 InitTriplet 重定义了! 大佬,是不是这意思啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-10 14:24:46 | 显示全部楼层
本帖最后由 风扫地 于 2019-5-10 14:28 编辑

#ifndef __文件名_H__  //  __文件名_H__ 这个可用按自己的习惯取,只要能保证不同文件名对应的防重复宏不会重复即可。
#define __文件名_H__
/* 都定义在这里面*/

#endif  // 这个#endif 不能漏掉


REF:
https://blog.csdn.net/andy001847/article/details/53240568
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-5-10 14:26:47 | 显示全部楼层
本帖最后由 qwe6620690 于 2019-5-10 14:34 编辑

谢谢.还真是这个原因,重编译了! 我试着在
  1. //bo1-1.c
  2. //加入 这个条件编译命令
  3. #ifdef CH1
  4. /*基本操作的实现*/
  5. Status InitTriplet(Triplet *T, ElemType v1, ElemType v2, ElemType v3)
  6. {
  7.         if (!(*T = (ElemType *)malloc(3 * sizeof(ElemType))))
  8.                 exit(OVERFLOW);

  9.         (*T)[0] = v1, (*T)[1] = v2, (*T)[2] = v3;

  10.         return OK;
  11. }
  12. #endif

  13. //在mian1-1.c 头部加入
  14. #define CH1
  15. //成功编译了!真心感谢
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-5-10 14:46:27 | 显示全部楼层
风扫地 发表于 2019-5-10 14:24
#ifndef __文件名_H__  //  __文件名_H__ 这个可用按自己的习惯取,只要能保证不同文件名对应的防重复宏不 ...

谢谢.问题解决了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-8 15:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表