VScode的C/C++语言环境配置
安装vscode以及相关插件以及C++编译器
首先没什么好说的,按照如下链接下载好VScode并且安装
之后,启动vscode,ctrl+shift+X,打开插件商店,我们来安装如下插件
其实VScode本质上是一个代码编辑器,并没有编译运行C/C++代码的能力,我们说是要配置C/C++开发环境,其实背后还是调用了我们电脑上其他地方的C/C++编译器,所以在最后,我们要安装。这里我推荐mingw64。其实这种资源是非常容易找到的,这里也就不提供链接了,实在找不到的可以私聊我。下载好mingw64对应的压缩包后,解压到你想要的位置,并将该目录下bin文件夹置添加到环境变量,具体怎么添加,我相信你肯定也会,原因也很简单,bin里面都是可执行文件嘛。配置好之后打开shell输入gcc,如果不报错,ok,那就证明你配置成功了。下面是我的mingw64路径以及对应的环境变量,以及输入gcc之后的效果
自动生成配置文件,进行运行&调试————配置默认生成任务
上课的时候也讲了,想要让vscode运行代码,也得写配置文件,往里面填GCC命令。当然,比如我们刷算法题时,面对只有一个源文件的小任务,我们可以不用手动配置,直接自动生成即可。键盘按住ctrl+shift+P,选择如下选项
即可自动生成配置文件。它不仅支持运行,还支持断点调试等实用功能。我们来看一下这些事情。
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
double func(double x)
{
return exp(x);
}
double prob(int a, int b, double c, double d, int n, double func(double x))
{
double square = (b - a) * d;
int count = 0;
int loop = n;
while (loop > 0)
{
double random_y = rand() / (double)RAND_MAX * d;
double random_x = rand() / (double)RAND_MAX * (b - a) + a;
double ans = func(random_x);
if (random_y <= ans)
{
count += 1;
}
loop -= 1;
}
double prob = (double)count / n;
return prob * square;
}
int main()
{
double ans = prob(0, 1, exp(0), exp(1), 10000000, func);
printf("%f", ans);
}
如上是一个求\(\int_{0}^{1}e^{x}dx\)的概率算法。我们按F5,在第25行上打上断点,看看我们能不能做到断点调试,并且查看变量值,走你。
你也看见了,所有的变量都能看得清清楚楚。那么这个算法最后能运行出正确结果吗?我们接着看。
\(\int_{0}^{1}e^{x}dx=e-1\approx1.71828\),和我们的结果非常相近,毕竟这是个数字概率算法,在循环次数较少的情况下,这已经很精确了。
使用cmake自动生成makefile
上课老师也讲了makefile,确实比手敲编译指令方便了点,但是这玩意学习成本也不低,自己写起来也烦。其实早就有自动生成makefile的工具可以用了,而且不止一种。
cmake可以在大型工程中自动生成makefile,关键在于 CMakeLists.txt这个配置文件
# 最低CMake版本要求
cmake_minimum_required(VERSION 3.10.0)
# 项目名称
project(cmake-test)
# 设置C/C++标准
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 头文件路径
include_directories("Inc")
# 枚举头文件
file(GLOB_RECURSE INCLUDES "Inc/*.h" "Inc/*.hpp")
# 枚举源文件
aux_source_directory("Src" SOURCES)
# 输出路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
# 生成可执行的文件
add_executable(${PROJECT_NAME} ${SOURCES} ${INCLUDES})
# 生成库文件,STATIC为静态库,SHARED为动态库
add_library(test STATIC src/test.cpp)
# 链接一个内部依赖库
target_link_libraries(Demo test)
动态库与静态库简介
除了生成可执行文件,我们还可以生成库文件.Windows中静态库.lib后
缀,动态库为.dll,linux中静态库.a后缀, 动
态库.so后缀
那么什么是库文件呢?分别来介绍一下
静态库文件:链接阶段,库中目标文件所含的所有将被程序使用的函数的机器码,被copy到最终的可执行文件中。
因此对应的链接方式称为静态链接。
特点
- 静态库对函数库的链接是放在编译时期完成的
- 程序在运行时与函数库再无瓜葛,移植方便
- 运行效率相对快
- 占用磁盘和内存空间,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。
局限性
- 空间浪费是静态库的一个问题
- 静态库对程序的更新、部署和发布页会带来
麻烦 - 如果静态库lib更新了,所以使用它的应用程
序都需要重新编译、发布给用户 - 对于玩家来说,可能是一个很小的改动,却
导致整个程序重新下载,全量更新
那什么是动态库呢?
程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。
特点
- 可执行文件只包含它需要的函数的引用表,而不是所有的函数代码
- 只有在程序执行时, 那些需要的函数代码才被拷贝到内存中
- 动态库在程序运行是才被载入,也解决了静态库对程序的更新、部署和发布页会带来麻烦。用户只
需要更新动态库即可,增量更新。 - 但依赖的模块也要存在,如果使用载入时动态链接,
程序启动时发现DLL不存在,系统将终止程序并给出
错误信息,依赖性强。
总结
- 静态库是牺牲了空间效率,换取了时间效率
- 共享库是牺牲了时间效率,换取了空间效率
工程应用
- 一般在比较固定参数的工程项目中,如底层驱动逻辑比较稳定,会考虑静态库的使用;
- 在需要多次调试优化版本中,比如PUBG(吃鸡)的游戏平衡体验更新,会考虑动态库的使用。
实战
我们将最开始的概率算法修改一下,把待计算函数部分和概率算法部分分别模块化,最后被一个main函数调用。目录结构如下,我们改为C++语言实现,这也是为了向大家演示,那个插件以及mingw也是支持C++的:
.
├── CMakeLists.txt
├── inc
│ ├── cal_func.h
│ └── prob.h
├── main.cpp
└── src
├── cal_func.cpp
├── CMakeLists.txt
└── prob.cpp
接下来我们编写src内部的CMakeLists.txt,用来生成静态库文件
# 最低CMake版本要求
cmake_minimum_required(VERSION 3.10.0)
# 头文件路径
include_directories("../inc")
aux_source_directory(. DIR_LIB_SRCS)
# 生成可执行的文件
add_library (static_lib STATIC ${DIR_LIB_SRCS})
我们执行cmake .来看下效果
你也看见了,我们通过cmake自动生成的makefile来生成了我们想要的libstatic_lib.a文件
我们最后写项目根目录的CMakeLists.txt
# 最低CMake版本要求
cmake_minimum_required(VERSION 3.10.0)
# 项目名称
project(prob_algo)
# 设置C/C++标准
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 添加 src 子目录
add_subdirectory(src bin)
include_directories(inc)
# 指定生成目标
add_executable(prob_algo main.cpp)
# 添加链接库
target_link_libraries(prob_algo static_lib)
我们来通过cmake .生成makefile,用make来编译,最后执行看看效果如何
你也看见了,在最后,我们使用cmake来编译的项目生成了正确的定积分值。