qwe6620690 发表于 2019-5-10 12:18:11

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

本帖最后由 qwe6620690 于 2019-5-10 14:35 编辑

/*c1.h*/
#include<string.h>
#include<ctype.h>
#include<malloc.h>        /*malloc()等*/
#include<limits.h>        /*INT_MAX等*/
#include<stdio.h>        /*EOF(= ^Z或F6),NULL*/
#include<stdlib.h>        /*atoi()*/
#include<io.h>                /*eof()*/
#include<math.h>        /*floor(),ceil(),abs()*/
#include<process.h>        /*exit()*/
/* 函数结果状态代码 */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
//#define OVERFLOW -2

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

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

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

typedef int ElemType;

#include"c1-1.h"

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

        (*T) = v1, (*T) = v2, (*T) = v3;

        return OK;
}

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

int main(void)
{
        Triplet T = NULL;
        ElemType m = 0;
        Status i;

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

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

        system("pause");
        return 0;
}

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

上面四个文件合一个文件正常编译,分开为什么出现重定义错误? 先谢过各位了!

wwhywhy 发表于 2019-5-10 13:11:53

把两个.h文件都包含,应该就可以了。
我理解的是:程序编译有顺序的。

qwe6620690 发表于 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语言中,被调函数在主调函数前定义,可以不需要用函数原型声明了!没出现重定义.编译为什么还提示重定义错误呢

wwhywhy 发表于 2019-5-10 13:49:37

本帖最后由 wwhywhy 于 2019-5-10 13:52 编辑

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

这样就不会重复包含了

qwe6620690 发表于 2019-5-10 13:58:46

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

额,好像忘了一细节了,编译器编译是以文件为单位进行编译,在bo1-1.c编译过一次了,然后又给包含进main1-1.c文件里,重新编译一次,这样就出现了重编译问题,输出结果就成 InitTriplet 重定义了! 大佬,是不是这意思啊

风扫地 发表于 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

qwe6620690 发表于 2019-5-10 14:26:47

本帖最后由 qwe6620690 于 2019-5-10 14:34 编辑

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

        (*T) = v1, (*T) = v2, (*T) = v3;

        return OK;
}
#endif

//在mian1-1.c 头部加入
#define CH1
//成功编译了!真心感谢

qwe6620690 发表于 2019-5-10 14:46:27

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

谢谢.问题解决了
页: [1]
查看完整版本: 求助分文件写出现重定义,和一起写,正确编译,这是为什么?