鱼C论坛

 找回密码
 立即注册
查看: 3712|回复: 12

[已解决]C++:需要include".cpp"文件,不include就报错“无法解析的外部符号”

[复制链接]
发表于 2019-6-6 20:37:55 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 菜鸟小乔 于 2019-6-6 20:50 编辑

代码功能:静态链表的初始化、插入、打印。
问题描述:之前写代码一直是分3个文件:.h文件声明函数,.cpp文件实现函数,main.cpp文件调用函数,两个.cpp文件都只include自定义的 .h文件,没有出过问题。
但这一次main.cpp文件需要include函数实现的“.cpp”文件,否则就会报错“无法解析的外部符号(后面是自定义的函数名)”。

错误        LNK2019        无法解析的外部符号 "void __cdecl PrintSLL(struct <unnamed-type-SLL> * const)" (?PrintSLL@@YAXQAU<unnamed-type-SLL>@@@Z),该符号在函数 _main 中被引用        ch4        C:\Users\ELEVEN\Desktop\ch4\main.obj       


代码本身没什么问题,就是想问为什么这一次一定要include .cpp文件呢?之前同样的套路从没有include 过.cpp文件。
---------------demo.h文件---------------
#ifndef demo_h_include
#define demo_h_include
#include<iostream>
using namespace std;

#define MAX_SIZE 10

struct eleType {
        int id;
        string name;
};

typedef struct {
        eleType data;
        int next;
}SLL[MAX_SIZE];

void Init(SLL list_s);//初始化函数

void PrintSLL(SLL list_s);//打印函数

int insertSLL(SLL list_s, int pos,eleType element);//插入函数

int newSLL(SLL list_s);//为静态链表分配内存,返回0表示分配失败

#endif
---------------sll_demo.cpp文件---------------
#include<iostream>
#include"demo.h"
using namespace std;

void Init(SLL list_s)//初始化
{
        for (int i = 0; i < MAX_SIZE; i++)
        {
                list_s[i].next = i + 1;
        }
        list_s[MAX_SIZE-1].next = 0;
        list_s[MAX_SIZE-2].next = 0;
        return ;
}
////////////////////////插入函数/////////////////////
int insertSLL(SLL list_s, int pos, eleType element)
{
        int cursor = MAX_SIZE - 1;//得到第一个元素下标
        //判断cursor范围是否合法

        //分配内存
        int newIndex = newSLL(list_s);
        if (newIndex)//不为零
        {
                list_s[newIndex].data = element;
                //找到newindex前缀节点
                for (int i = 1; i < pos - 1; i++)
                {
                        cursor = list_s[cursor].next;
                }
                list_s[newIndex].next = list_s[cursor].next;
                list_s[cursor].next = newIndex;
                return 1;
        }
        return 0;
}
/////////////////分配内存函数/////////////////
int newSLL(SLL list_s)
{
        int cursor = list_s[0].next;//得到第一个空闲节点下标
        if (cursor)
        {
                list_s[0].next = list_s[cursor].next;//新的空闲节点指向这个节点的下一个
        }
        return cursor;
}
//////////////////////打印函数//////////////////////////
void PrintSLL(SLL list_s)
{
        for (int i = 0; i < 10; i++)
        {
                cout<<"i:"<<i 
                        << " next:" << list_s[i].next <<"\t"
                        <<"id:"<<list_s[i].data.id << "\t"
                        <<"name:"<<list_s[i].data.name<< endl;
        }
        cout << "---------打印完毕----------" << endl;
}
-------------------main.cpp------------------
#include<iostream>
#include"demo.h"
#include"sll_demo.cpp"        //这一句,不加就会报错“无法解析的外部符号Init、PrintSLL。”
using namespace std;



int main()
{
        
        

        SLL list1;
        Init(list1);
        PrintSLL(list1);
        return 0;
}
最佳答案
2019-6-6 21:04:52
菜鸟小乔 发表于 2019-6-6 20:58
我发现我把.h文件定义结构数组那里:大括号前加个A就可以不用include .cpp文件了,这是什么道理?
typedef struct A{
        eleType data;
        int next;
}SLL;

SLL是struct A的别名

typedef struct {
        eleType data;
        int next;
}SLL;


SLL是谁的别名?
SLL不是谁的别名,那么报错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-6-6 20:46:47 | 显示全部楼层
你是用什么编译器?要是linux下面你要把两个cpp全编译了才行,不然肯定找不到的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-6-6 20:51:36 | 显示全部楼层
Krant5 发表于 2019-6-6 20:46
你是用什么编译器?要是linux下面你要把两个cpp全编译了才行,不然肯定找不到的

用的VS,之前一直都是分三个文件写代码的,从来没有include过.cpp文件,以前都没出过这个问题。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-6 20:58:34 | 显示全部楼层
1.的确是你的代码有问题
2.绝对不要include .cpp文件,绝对不要,除非你知道这样做会发生什么,并且知道为什么会发生,我直到现在都没有找到include .cpp文件的应用场合
#ifndef demo_h_include
#define demo_h_include
#include<iostream>
using namespace std;

#define MAX_SIZE 10

struct eleType {
        int id;
        string name;
};

//typedef struct {
typedef struct SLL_tag{
        eleType data;
        int next;
}SLL[MAX_SIZE];

void Init(SLL list_s);//初始化函数

void PrintSLL(SLL list_s);//打印函数

int insertSLL(SLL list_s, int pos,eleType element);//插入函数

int newSLL(SLL list_s);//为静态链表分配内存,返回0表示分配失败

#endif
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-6-6 20:58:37 | 显示全部楼层
Krant5 发表于 2019-6-6 20:46
你是用什么编译器?要是linux下面你要把两个cpp全编译了才行,不然肯定找不到的

我发现我把.h文件定义结构数组那里:大括号前加个A就可以不用include .cpp文件了,这是什么道理?
typedef struct A{
        eleType data;
        int next;
}SLL[MAX_SIZE];
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-6 20:59:20 | 显示全部楼层
#include<iostream>
#include"demo.h"

using namespace std;



int main()
{
        
        

        SLL list1;
        Init(list1);
        PrintSLL(list1);
        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-6 21:02:15 | 显示全部楼层
菜鸟小乔 发表于 2019-6-6 20:58
我发现我把.h文件定义结构数组那里:大括号前加个A就可以不用include .cpp文件了,这是什么道理?
https://fishc.com.cn/forum.php?mod=viewthread&tid=140818
1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-6 21:04:52 | 显示全部楼层    本楼为最佳答案   
菜鸟小乔 发表于 2019-6-6 20:58
我发现我把.h文件定义结构数组那里:大括号前加个A就可以不用include .cpp文件了,这是什么道理?
typedef struct A{
        eleType data;
        int next;
}SLL;

SLL是struct A的别名

typedef struct {
        eleType data;
        int next;
}SLL;


SLL是谁的别名?
SLL不是谁的别名,那么报错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-6-6 21:30:56 | 显示全部楼层
人造人 发表于 2019-6-6 21:04
SLL是struct A的别名

typedef struct {
        eleType data;
        int next;
}SLL;

我明白了,其实上面这样写不会报错,只是:警告        C5046         “PrintSLL”: 未定义涉及内部链接类型的符号。

相当于{}前面那个A是本名,是“内部链接类型的符号”;如果没给本名,只给了一个别名SLL,而这个别名是没有被赋予所谓“内部链接”作用的。所以一旦我们调用这个SLL类型,就无法实现“内部链接”;所以才需要include那个.cpp文件,相当于手动链接一下。(我是看一个C的数据结构的视频写的代码,发现跟C++还是挺多差异的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-6 21:33:44 | 显示全部楼层
菜鸟小乔 发表于 2019-6-6 21:30
typedef struct {
        eleType data;
        int next;

绝对不要include .cpp文件
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-6-6 21:39:50 | 显示全部楼层
人造人 发表于 2019-6-6 21:33
绝对不要include .cpp文件

记住了,多谢~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-6 22:30:17 | 显示全部楼层
菜鸟小乔 发表于 2019-6-6 21:30
typedef struct {
        eleType data;
        int next;

在 C里面是不用写的,只不过C++的结构体已经跟class一样了,只是权限不同而已,所以有问题.
C中都可以,一般可以写类似于
typedef struct dev_info {
int dev_id;
int dev_type;
} T_dev_info;
//或者直接
typedef struct {
int dev_id;
int dev_type;
} T_dev_info;
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-6-10 12:18:53 | 显示全部楼层
Krant5 发表于 2019-6-6 22:30
在 C里面是不用写的,只不过C++的结构体已经跟class一样了,只是权限不同而已,所以有问题.
C中都可以,一 ...

哦哦,知道啦,谢谢啦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-10-3 21:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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