VSCode开发C、C++环境搭建系列(一)——基于Mingw-w64搭建_vscode mingw64-程序员宅基地

技术标签: VSCode开发C和C++  C/C++  Mingw-w64 Cygwin Msys2  MSVC  posix win32  windows开发C环境搭建  

前言:本次系列文章详细说明基于VS Code来搭建C、C++的开发环境,本次的操作系统是Windows系统,在Windows上面,会有两种不同主流编译器,及Mingw-W64和MSVC,本文介绍第一种,是系列文章的第一篇。

概念辨析:

Mingw-w64。是 GCC 的 Windows 版本 ;

Cygwin。是一个在windows平台上运行的类UNIX模拟环境,在Windows上面提供类似与Linux的开发环境,但是需要注意的是,在Linux上面的程序并不能直接拿过来运行,而是需要在Cygwin环境之下重新编译才行;

MSYS2。是一个体验非常好的linux模拟环境,可以移植大多数linux上面的程序,起源于cygwin,是Cygwin的一个升级版本。

一、Mingw-w64介绍以及如何安装

1.1 什么是Mingw-w64?

MinGW 的全称是:Minimalist GNU on Windows 。它实际上是将经典的开源 C语言 编译器 GCC 移植到了 Windows 平台下,并且包含了 Win32API ,因此可以将源代码编译为可在 Windows 中运行的可执行程序。而且还可以使用一些 Windows 不具备的,Linux平台下的开发工具。一句话来概括:MinGW 就是 GCC 的 Windows 版本 。

以上是 MinGW 的介绍,MinGW-w64 与 MinGW 的区别在于 MinGW 只能编译生成32位可执行程序,而 MinGW-w64 则可以编译生成 64位 或 32位 可执行程序。正因为如此,MinGW 现已被 MinGW-w64 所取代,且 MinGW 也早已停止了更新,内置的 GCC 停滞在了 4.8.1 版本,而 MinGW-w64 内置的 GCC 则更新到了 6.2.0 版本。

1.2 安装Mingw-w64

Mingw-w64的安装有两种方式,在线安装和离线形式,其中在线形式有时候会遇到各种问题,比如什么cann't download repository.txt,尚没有找到好的解决办法,关于在线安装可以参考这篇文章。

MinGW-w64安装教程——著名C/C++编译器GCC的Windows版本

离线形式非常简单,解压即可以使用,不需要往外安装,但是需要选择正确合适的版本和相关配置才行,

离线下载的网址为:

https://sourceforge.net/projects/mingw-w64/files/?source=navbar

界面如下所示:

我们发现每一个版本里面有8个不同的文件,那到底选择哪一个呢?这里需要涉及到一些基础知识,我将在下面分别介绍。

(1)电脑的处理器架构Architecture

Architecture 是指电脑处理器是 32位 还是 64位,根据你的电脑系统做出对应选择。我的电脑处理器是 64位 的,所以我选择了 x86_64,如果你是 32位 系统,则选择 i686 即可。注意,下面是可以选择的Architecture类型:

1、i386   通常被用来作为对Intel(英特尔)32位微处理器的统称;

2、i686   是i386的子集,也是针对32位的处理器

3、x86-64   又称“AMD64”或“x64”,是一种64位元的电脑处理器架构。它是建基于现有32位元的x86架构,由AMD公司所开发。

(2)操作系统接口协议threads

这个世界上只有两种操作系统接口协议,即所谓的posix和win32,如果你想要开发 Windows 程序,需要选择 win32 ,而开发 Linux、Unix、Mac OS 等其他操作系统下的程序,则需要选择 posix 。其实是什么意思呢?就是在这两个不同的协议之下,有很多函数接口是不一样的,比如在Linux上面的C程序不能直接拿到Windows上面运行,因为有一些函数库是不一样的。

操作:我只开发在 Windows 下运行的程序,所以选择了 win32 。

但是,我们依然更加推荐选择POSIX,为什么呢?

  • posix :启用C ++ 11 / C11多线程功能。 比如我们希望编译OpenCV,需要用到C++ 11的多线程里面的一些类,如果使用的是win32,就会报错,因为win32没有这些类。
  • win32 :没有C ++ 11多线程功能。

那是不是意味着如果我要使用win32的 API,就不能使用POSIX呢?

不是的。其实GCC带有一个编译器运行库(libgcc),它用于(除其他外)提供一个底层操作系统抽象,用于支持多语言相关功能。 最相关的例子是libstdc ++的C ++ 11 <thread> , <mutex><future> ,当使用内部的Win32线程模型构建GCC时,没有完整的实现。 MinGW-w64提供了一个winpthreads(在Win32多线程API之上的一个pthreads实现),然后GCC可以链接到所有的奇特功能。

综上所述,我们选择:POSIX 更好!!!

那到底什么是POSIX呢?

POSIX:可移植操作系统接口,是 IEEE 为要在各种 UNIX 操作系统上运行软件,而定义API的一系列互相关联的标准的总称。

(3)异常处理模型Exception

异常处理在开发中非常重要,你在开发的过程中,大部分的时间会耗在处理各种异常情况上。又分为几种情况:

x86_64 即64位处理器。如果你之前选择了 64位,则这里有两个异常处理模型供你选择,seh 是新发明的,而 sjlj 则是古老的,seh 性能比较好,但不支持 32位。 sjlj 稳定性好,支持 32位。我选择seh.

i686 即32位处理器。选择了 32位 后,则可以用 dwarf 和 sjlj 两种异常处理模型。同样的,dwarf 的性能要优于 sjlj ,可以它不支持 64位 。建议选择 dwarf 。

总结:Mingw-w64的离线文件命名格式为“architecture+threads+exception",我选择的是上面图片中蓝色圈出来的那个。

下载之后的压缩文件大小为47M多,下载之后进行解压,解压之后大概430M多,放在任意位置即可,由于不需要安装,我将其解压到下面的文件位置:

D:\Program Files\mingw64

里面包含的文件以及文件夹有

打开里面的那个bin文件夹,里面包含几个关键的可执行程序,包括:

  • gcc.exe
  • g++.exe
  • mingw32-make.exe,这个就相当于是Linux下面的make.exe。单个按我们也可以创建一个他的副本,重命名为make.exe.
  • gdb.exe 用于调试的
  • cpp.exe 是专门用于预处理的
  • as.exe 是专门用于进行汇编的
  • ld.exe 是专门进行链接的

现在需要将这个bin目录添加到环境变量PATH里面。然后在cmd中查看如下:

C:\Users\Administrator>gcc --version
gcc (x86_64-win32-seh-rev0, Built by MinGW-W64 project) 8.1.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


C:\Users\Administrator>g++ --version
g++ (x86_64-win32-seh-rev0, Built by MinGW-W64 project) 8.1.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.



C:\Users\Administrator>mingw32-make --version
GNU Make 4.2.1
Built for x86_64-w64-mingw32
Copyright (C) 1988-2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

现在gcc,g++,make都可以使用了。

(4)关于异常处理,Eception Handle (EH)

sjlj :基于 > setjmp / longjmp(SJLJ)

seh: 结构化异常处理(SEH)

dwarf :dwarf-2 , dwarf-3

 

二、做一个简单的C++程序

由于多文件的C++程序在编译的时候相对较为麻烦,本文的例子是在一个单独的CPP文件中而言的,使用vscode的主要步骤就三个步骤。

先打开VSCode,打开一个空文件夹,然后开始配置。要是本来对VSCode比较熟悉就很容易入手了。

2.1 配置编译器路径(Configure the compiler path)及其他信息

实际上会在打开的文件中打开一个.vscode的文件夹,里面会配置一个c_cpp_properties.json配置文件,配置方法:

打开命令面板,Ctrl+Shift+P 

然后输入 "C/C++:Edit Configurations (UI)" ,然后会打开一个配置的界面,有以下几个地方需要配配置:

(1)Configuration name

有三个选项可供选择. LinuxMac, 和 Win32,默认就是Win32,不用再管这个了。

(2)编译器的路径Compiler path

这个是最核心的配置,即所谓的编译器的完整路径,比如我的路径是:

D:/Program Files/mingw64/bin/gcc.exeD:/Program Files/mingw64/bin/g++.exe

(3)编译器的参数 Compiler arguments

编译器本质上还是一个可执行程序,他有很多的命令参数可以传递,这里是一个简单的编译,可以不用设置参数,即可

(4)智能感知 IntelliSense mode

这是代码智能感知的设置,需要和我们选择的编译器MSVC,gcc(g++),Clang,相对应,有以下几个选项可以选择,

 ${default}             

clang-x86             

clang-x64           

gcc-x86             

gcc-x64           

msvc-x86             

msvc-x64         

如果不设置则选择${default}即可。

(5)函数库的路径 Include path

这个路径就是包含各种需要的函数库以及头文件的文件夹,我们可以自己手动设置,但是如果我们已经设置好了编译器的路径,即前面的第(2)个步骤,就不用再显示给出搜索路径了,编译器会自动进行查找。我们只需要设置成默认值就可以了,如下:

${workspaceFolder}/**

这里后面跟一个 /** 符号表示会再这个目录之下的子目录递归搜索。

注意:VS Code中,头文件,静态链接库,动态链接库这三者都是要在这里面进行指定的哦!!!这里的include不仅仅包含头文件。

(6)Defines

这个我还不是很清楚到底有什么作用,直接使用默认值吧,如下:

_DEBUG
UNICODE
_UNICODE

(7)C standard

C语言的标准,当前有三个标准: c11 、c99 、 c89             

(8)C++ standard

C++语言的标准,有以下几个:c++20、 c++17 、c++14、c++11、c++03、c++98             

上面的是一些较为常规的设置,下面还有一些比较高级的设置,就不再一一说明了,直接列举如下:

Configuration provider

Windows SDK version

Mac framework path

Forced include

Compile commands

Browse: path

Browse: limit symbols to included headers

Browse: database filename

 配置之后的c_cpp_properties.json文件如下所示:

{
    "configurations": [
        {
            "name": "Win32",                                            // 对应(1)
            "includePath": [                                            // 对应(5)
                "${workspaceFolder}/**"
            ],
            "defines": [                                                // 对应(6)
                "_DEBUG",
                "UNICODE",
                "_UNICODE"
            ],
            "compilerPath": "D:\\Program Files\\mingw64\\bin\\g++.exe", // 对应(2)
            "cStandard": "c11",                                         // 对应(7)
            "cppStandard": "c++17",                                     // 对应(8)
            "intelliSenseMode": "gcc-x64"  //对应(4)
        }
    ],
    "version": 4
}

 如果要添加或者是删除某一些配置,直接删除或者更改即可。  

2.2 配置任务Tasks

这会产生一个 tasks.json 文件,这个文件会告诉VSCode,怎么去编译(build/compile)程序,所谓的任务其实就是交给编译器G++去做,让它产生一个可执行文件。怎么配置呢?

执行”终端/配置任务“菜单,或者是CTRL+Shift+P打开命令面板,输入:Tasks: Configure Default Build Task.

然后选择从模板创建tasks.json,选择其他others, 会打开一个tasks.json文件。大概会得到下面的一些内容:

{
    "version": "2.0.0",
    "tasks": [
      {
        "label": "build hello world",
        "type": "shell",
        "command": "g++",
        "args": ["-g", "-o", "helloworld", "helloworld.cpp"],
        "group": {
          "kind": "build",
          "isDefault": true
        }
      }
    ]
  }

下面对几个重要的概念进行解释:

(1)label:这只是一个标签,是我们能够在VSCode里面看得见的,我们可以随便自己定义名称;

(2)type:任务的类型,可以是either或者是process,如果设定为shell,则表示任务会被解释成shell命令执行(bash,cmd,powershell),如果指定成process,任务会被解释成一个进程去执行。

(3)command:实际执行的命令,这里是g++,也可以是gcc,或者是MSVC之下的cl.exe。

(4)args: 就是(3)中命令g++的命令行参数

(5)group:设置group的之之后,当按下Ctrl+Shift+B,实际上也就是菜单命令”终端/运行生成任务...“,就会执行该任务(这个任务就是编译程序)里面有两个参数,分别的含义如下:

kind:定义此任务属于的执行组。它支持 "build" 以将其添加到生成组,也支持 "test" 以将其添加到测试组。

isDefault: 设置成true的话,当按下 Ctrl+Shift+B. 任务就会执行,这很方便;如果设置成false,则需要在面板中执行:Tasks: Run Build Task.才能执行任务。

此外还有一些常见的选项,这里就不再一一列举了。我们可以自己查看,比如我想查看全部的参数,只需要自己在添加一个,输入一个引号,VSCode会自己感知,自己选择即可。

运行编译任务之后,会再当前目录下面产生一个 exe 的可执行文件,下面就可以直接执行这个可执行文件或者是调试它。

 

2.3 配置调试debug设置Configure debug settings

当我们按下F5的时候就会启动GCC的调试器,即前面介绍的gdb.exe.但是在调试之前需要配置,怎么配置呢?

执行”调试/添加配置...“,菜单,或者是再命令面板执行Debug: Open launch.json.

接下来选择 GDB/LLDB(launch) 调试环境,如果是使用MSVC编译器的话,则选择C/C++ Windows (Launch)调试环境。

然后就会打开一个launch.json文件,配置如下:

{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [

        {
            "name": "(gdb) Launch",   //配置的名称,在启动配置下拉菜单中显示的名称,一般不用修改
            "type": "cppdbg",         //配置类型
            "request": "launch",      //请求配置类型,可以是"launch"或者是"attach"
            "program": "${workspaceFolder}/helloworld.exe", // 可执行程序的完整路径
            "args": [],               // 可执行程序的命令行参数
            "stopAtEntry": false,     // 默认是false,如果设置成true,则就算没有设置断点,按F5开始调试,也会在程序的入口处停下,即main函数的第一句话就相当于设置了断点
            "cwd": "${workspaceFolder}", // 可执行程序的工作路径
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",          //"gdb"或者是"lldb",可以将鼠标悬停在上面查看详细描述
            "miDebuggerPath": "D:\\Program Files\\mingw64\\bin\\gdb.exe", //调试器的路径所在
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

上面的 2.1 、2.2 、2.3 这三个步骤就是一般的配置,配置之后就可以开始C++编程。

总结:VSCode开发C、C++的配置三部曲:

2.1 配置编译器路径(Configure the compiler path)及其他信息

产生  c_cpp_properties.json

2.2 配置任务Tasks

产生  tasks.json

2.3 配置调试debug设置Configure debug settings

产生  launch.json

三、一个简单的C++程序

新建一个helloworld.cpp文件,如下内容:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

//自定义一个函数
int add(int a,int b)
{
    return a+b;
}

int main()
{

    vector<string> msg {"Hello", "C++", "World", "from", "VS Code!"};
    
    for (const string& word : msg)
    {
        cout << word << " ";
    }
    cout << endl;
    int c;
    c=add(100,200);
    printf("a+b=%d",c);
}

3.1 编译(build/compile)

执行 ”终端/运行生成任务...“ 或者是按快捷键 Ctrl+Shift+B ,则开始了编译过程,在终端会显示这样一句话:

> Executing task: g++ -g -o helloworld helloworld.cpp <

这就是使用g++进行编译的过程嘛。完成之后,会在当前目录之下出现一个helloworld.exe的可执行文件。

3.2 调试或者是执行

直接执行,按下Ctrl+F5,得到如下结果:

Hello C++ World from VS Code! 
a+b=300

或者设置断点,按F5进行调试。

 

四、GCC编译器在编译的时候如何找寻函数库与头文件

前面说了在Mingw-w64的目录之下,有include和lib等一系列的文件夹,都是编译器自带的头和库,你要的标准库头文件就在这里。对普通用户来说我们别别往里乱放东西。当然你的第三方库可以放在这里,这些目录都是mingw64会默认搜索的路径,在这两目录下也有些编译带的库。

那么GCC如何找到这里的呢,及如何搜索到的呢?

在比较老的Mingw编译器上,我们需要设置下面几个环境变量:

  • C_INCLUDE_PATH            // C的头文件库,一个或者是多个路径
  • CPLUS_INCLUDE_PATH  //C++的头文件库,一个或者是多个路径
  • OBJC_INCLUDE_PATH      //objective-C的头文件
  • LIBRARY_PATH                 // 标准库函数的路径(静态库)
  • LD_LIBRARY_PATH          //  动态库

以上三个变量的路径的,而最近几版的Mingw64只要设置好bin目录环境变量(主目录下的bin目录),编译器就会自己在以上的头和库的路径中自动查找了,但你仍然可以手动指定。

其实用户头和库无所谓放哪,都是可以用参数指定的。而且很多第三方库带pkg-config。可以轻松得到编译参数(包括了头和库的路径)

关于GCC更加详细的用法,后面会有专门的文章进行讲解的。
 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_27825451/article/details/102531426

智能推荐

分布式光纤传感器的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告_预计2026年中国分布式传感器市场规模有多大-程序员宅基地

文章浏览阅读3.2k次。本文研究全球与中国市场分布式光纤传感器的发展现状及未来发展趋势,分别从生产和消费的角度分析分布式光纤传感器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品的价格、产量、产值及全球和中国市场主要生产商的市场份额。主要生产商包括:FISO TechnologiesBrugg KabelSensor HighwayOmnisensAFL GlobalQinetiQ GroupLockheed MartinOSENSA Innovati_预计2026年中国分布式传感器市场规模有多大

07_08 常用组合逻辑电路结构——为IC设计的延时估计铺垫_基4布斯算法代码-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏12次。常用组合逻辑电路结构——为IC设计的延时估计铺垫学习目的:估计模块间的delay,确保写的代码的timing 综合能给到多少HZ,以满足需求!_基4布斯算法代码

OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版-程序员宅基地

文章浏览阅读3.3k次,点赞3次,收藏5次。OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版

关于美国计算机奥赛USACO,你想知道的都在这_usaco可以多次提交吗-程序员宅基地

文章浏览阅读2.2k次。USACO自1992年举办,到目前为止已经举办了27届,目的是为了帮助美国信息学国家队选拔IOI的队员,目前逐渐发展为全球热门的线上赛事,成为美国大学申请条件下,含金量相当高的官方竞赛。USACO的比赛成绩可以助力计算机专业留学,越来越多的学生进入了康奈尔,麻省理工,普林斯顿,哈佛和耶鲁等大学,这些同学的共同点是他们都参加了美国计算机科学竞赛(USACO),并且取得过非常好的成绩。适合参赛人群USACO适合国内在读学生有意向申请美国大学的或者想锻炼自己编程能力的同学,高三学生也可以参加12月的第_usaco可以多次提交吗

MySQL存储过程和自定义函数_mysql自定义函数和存储过程-程序员宅基地

文章浏览阅读394次。1.1 存储程序1.2 创建存储过程1.3 创建自定义函数1.3.1 示例1.4 自定义函数和存储过程的区别1.5 变量的使用1.6 定义条件和处理程序1.6.1 定义条件1.6.1.1 示例1.6.2 定义处理程序1.6.2.1 示例1.7 光标的使用1.7.1 声明光标1.7.2 打开光标1.7.3 使用光标1.7.4 关闭光标1.8 流程控制的使用1.8.1 IF语句1.8.2 CASE语句1.8.3 LOOP语句1.8.4 LEAVE语句1.8.5 ITERATE语句1.8.6 REPEAT语句。_mysql自定义函数和存储过程

半导体基础知识与PN结_本征半导体电流为0-程序员宅基地

文章浏览阅读188次。半导体二极管——集成电路最小组成单元。_本征半导体电流为0

随便推点

【Unity3d Shader】水面和岩浆效果_unity 岩浆shader-程序员宅基地

文章浏览阅读2.8k次,点赞3次,收藏18次。游戏水面特效实现方式太多。咱们这边介绍的是一最简单的UV动画(无顶点位移),整个mesh由4个顶点构成。实现了水面效果(左图),不动代码稍微修改下参数和贴图可以实现岩浆效果(右图)。有要思路是1,uv按时间去做正弦波移动2,在1的基础上加个凹凸图混合uv3,在1、2的基础上加个水流方向4,加上对雾效的支持,如没必要请自行删除雾效代码(把包含fog的几行代码删除)S..._unity 岩浆shader

广义线性模型——Logistic回归模型(1)_广义线性回归模型-程序员宅基地

文章浏览阅读5k次。广义线性模型是线性模型的扩展,它通过连接函数建立响应变量的数学期望值与线性组合的预测变量之间的关系。广义线性模型拟合的形式为:其中g(μY)是条件均值的函数(称为连接函数)。另外,你可放松Y为正态分布的假设,改为Y 服从指数分布族中的一种分布即可。设定好连接函数和概率分布后,便可以通过最大似然估计的多次迭代推导出各参数值。在大部分情况下,线性模型就可以通过一系列连续型或类别型预测变量来预测正态分布的响应变量的工作。但是,有时候我们要进行非正态因变量的分析,例如:(1)类别型.._广义线性回归模型

HTML+CSS大作业 环境网页设计与实现(垃圾分类) web前端开发技术 web课程设计 网页规划与设计_垃圾分类网页设计目标怎么写-程序员宅基地

文章浏览阅读69次。环境保护、 保护地球、 校园环保、垃圾分类、绿色家园、等网站的设计与制作。 总结了一些学生网页制作的经验:一般的网页需要融入以下知识点:div+css布局、浮动、定位、高级css、表格、表单及验证、js轮播图、音频 视频 Flash的应用、ul li、下拉导航栏、鼠标划过效果等知识点,网页的风格主题也很全面:如爱好、风景、校园、美食、动漫、游戏、咖啡、音乐、家乡、电影、名人、商城以及个人主页等主题,学生、新手可参考下方页面的布局和设计和HTML源码(有用点赞△) 一套A+的网_垃圾分类网页设计目标怎么写

C# .Net 发布后,把dll全部放在一个文件夹中,让软件目录更整洁_.net dll 全局目录-程序员宅基地

文章浏览阅读614次,点赞7次,收藏11次。之前找到一个修改 exe 中 DLL地址 的方法, 不太好使,虽然能正确启动, 但无法改变 exe 的工作目录,这就影响了.Net 中很多获取 exe 执行目录来拼接的地址 ( 相对路径 ),比如 wwwroot 和 代码中相对目录还有一些复制到目录的普通文件 等等,它们的地址都会指向原来 exe 的目录, 而不是自定义的 “lib” 目录,根本原因就是没有修改 exe 的工作目录这次来搞一个启动程序,把 .net 的所有东西都放在一个文件夹,在文件夹同级的目录制作一个 exe._.net dll 全局目录

BRIEF特征点描述算法_breif description calculation 特征点-程序员宅基地

文章浏览阅读1.5k次。本文为转载,原博客地址:http://blog.csdn.net/hujingshuang/article/details/46910259简介 BRIEF是2010年的一篇名为《BRIEF:Binary Robust Independent Elementary Features》的文章中提出,BRIEF是对已检测到的特征点进行描述,它是一种二进制编码的描述子,摈弃了利用区域灰度..._breif description calculation 特征点

房屋租赁管理系统的设计和实现,SpringBoot计算机毕业设计论文_基于spring boot的房屋租赁系统论文-程序员宅基地

文章浏览阅读4.1k次,点赞21次,收藏79次。本文是《基于SpringBoot的房屋租赁管理系统》的配套原创说明文档,可以给应届毕业生提供格式撰写参考,也可以给开发类似系统的朋友们提供功能业务设计思路。_基于spring boot的房屋租赁系统论文

推荐文章

热门文章

相关标签