当前位置: 首页 > news >正文

嵌入式开发学习 C++:day01

C++概述

C++诞生

1972年前后,计算机先驱丹尼斯·里奇开始设计C语言并用它来重写Unix系统,里奇的这个决定催生了计算机领域最石破天惊的两门重炮:Unix和C,这两者都是IT产业中鼻祖级的存在,Unix是现代苹果系统和Linux系统的最初来源,而C则是现代众多编程语言的思想源泉。后来随着IT产业的发展,C语言加入了诸如面向对象、泛型编程等新特性,在1983年前后,贝尔实验室的Biarne Strau-strup(本贾尼·斯特劳斯特卢普)推出了现代编程界中威力最猛的一门重炮:C++。

c++之父「Bjarne Strou-strup」
c++之父「Bjarne Strou-strup」

C++进一步扩充和完善C语言,成为一种多种编程范式的程序设计语言。从其名称可以推断,这种编程语言与C语言有密切的联系,实际上它们通常被合称为C/C++,它们的关系主要体现在以下两点:

  • C++是C语言的超集, C语言是C++语言联邦的一部分。
  • C++完全兼容C语言,并提供众多火力强大的现代编程范式

在这里插入图片描述

C与C++

据统计,当今世界上不同的编程语言有几百种之多, C++是使用最广泛的编程语言之一,是名副其实的顶流。 C++强大的同时,也是一门比较复杂的语言,它还包括函数式编程、泛型编程等不同的编程范式,有人说C++不是一门编程语言,而是众多编程语言的合集。

C++能干什么

C++主要用在开发系统、算法核心、游戏引擎等对性能高度敏感的领域,除了性能出众, C++的高安全性也是首屈一指的。下面简单罗列C++在IT各开发领域所展露的强大生
命力。

游戏 C++非常适合开发游戏,它的超前设计在应对3D游戏的复杂性时游刃有余, C++对网络的良好支持使得开发大型多人同时在线游戏成为可能,更进一步,由于C++允许直接控制硬件,因此能极大释放CPU的潜能,这种高性能使得C++被广泛应用于不同的游戏和游戏引擎。

在这里插入图片描述

动画 许多动画软件都是用C++开发的, C++非常适合用于图像处理、视觉效果呈现等典型的资源消耗型软件,比如:三维动画、建模、仿真、渲染,尤其是虚拟现实VR的场景和角色创建。

在这里插入图片描述

浏览器 C++也适合于用来开发浏览器,比如微软著名浏览器IE,谷歌的 Chrome Fire Fox 等,都是C++编写的, C++还是谷歌和Mozilla开源项目的核心呈现引擎的编程语
言。

在这里插入图片描述

数据库 C++在数据库软件开发中也占据非常重要的地位,最流行的数据库管理软件 MySQ L 就是其中一例, C++有助于节省时间、成本,提高业务系统的开发效率,还有大量基于
数据库软件访问的应用程序,主要都使用C++开发,这使得数据库访问快速、准确。

在这里插入图片描述

多媒体 C++当然可以用于创建媒体播放器,管理音视频文件等,它使得我们享受音乐,访
问和分享视频和音乐文件。相关的C++类库还具有艺术支持、音频和视频流媒体等功能。
甚至提供互联网无线电台的接入。

在这里插入图片描述

编译系统 大多数的编译器都使用C++开发,编译器是一种将计算机语言翻译成机器指令的特殊软件,比如C#、 Java等语言的编译器都是由C++进行翻译,然后才能交给CPU去运行。 C++在底层层面为各种各样软件的移植性提供支持。

​ 从这方面理解, C和C++是编写其他语言的语言,是许多编程语言的母语言。

操作系统 开发编译系统和操作系统,从某种程度上讲是C/C++当初被设计出来的初衷,如今世界上通行的底层操作系统几乎全部都是C/C++开发的,比如微软的 Windows2000 XP Unix/Linux 系统,安卓系统和苹果公司的部分操作系统。

在这里插入图片描述

应用开发 图形应用软件领域也大量广泛使用C++开发,比如被著名的图形设计软件 Phot oShop Adobe系列软件,微软的 Office 办公套件和Visual Studio,还有大量应
用于人工智能领域的算法引擎。

小结

​ 由于出生年代较早, C/C++并不是最易用、语法结构最浅显的语言,这主要是因为早期的计算机资源有限,计算机科学家在开发C/C++的时候,最在意的是最终代码运行的效率,而远非代码编写的难易度,这导致C/C++可以支持非常贴近底层硬件细节的语法,抓地力非常强,因而学习曲线要比一般的编程语言陡峭,也就是对学习者的要求更高。

​ 但也正是因为以上原因, C/C++天生具有高性能的血统,在目前的IT产业中,凡是涉及底层系统、算法核心、游戏引擎等对性能敏感的领域, C/C++都扮演者着不可或缺的角色,因为这些部件哪怕1%的性能波动,都会对整个软件的体验带来本质的改变。 总体来讲, C/C++是一门难学易用的编程语言,是计算机编程领域的重装武器,一旦掌握,威力无比。

C++输入输出

概述

在C++ 中输入和输出操作可以通过标准库中的iostream头文件来实现。这个头文件提供了类和对象,用于处理输入流(istream)和输出流(ostream)。最常见的来个对象是cin(控制台输入)和cout (控制台输出)。

包含头文件

为了使用输入输出功能必须包含以下头文件#include <iostream>

输出到控制台

使用cout 对象可以将数据输出到控制台。<<运输符 (用于将数据插入到输出流中)。

cout相当于一个面向对象的结构体)

typedef struct 
{int id;char *name;
}Student;
Student stu;// stu是学生对象
//stu.id 和  stu.name 是对象的成员
基本用法
// 如果不想写std :: 可以在文件顶部添加声明,using namespace std;
std ::cout << "hello World";// 开口方向是数据流方向
// 类似于C语言中的 printf("hello world \n");
输出多个值
int number = 10;
std:: count << "number" <<"number"; // 输出:number :10

从控制台输入

使用cin对象可以从控制台读取用户输入。>> 运输符(用于从输入流中读取数据)

基本用法
int age;
std::cout << "请输入您的年龄";
std::cin >> "age";
std::cout << "您今年" << "age" << " 岁 " << " \n ";

处理字符串输入

对于字符串类型,建议使用getline函数,因为他可以读取包含空格的整行文本。

#include <string>std::string name ;// 字符串类型的变量
std::cout << "请输入您的名字";
std::getline(std::cin,name); // 相当于C语言中的scanf("%s",&name)
std::cout << "你好", << "name" << "!\n";

格式化输出

可以使用操纵器来格式化输出,例如设置数字的显示方式、填充字符等。

设置精度
double pi = 3.1415926;
std:: cout.self(std:: ios::fixed);// 固定小数点表示法
std:: cout.precision(2); // 和上面代码配套使用,设置小数保留为2
std:: cout<< "PI 的近似值:" << pi << "\n" ;// 输出结果,PI 的近似值:3.14
对齐方式
//c++ 标准库中的一个头文件, 提供了多种用于控制输入输出格式的操纵器( manipulators) , 通过使用`<iomanip>`, 可以方便的格式化输入输出数据, 例如试着小数位数、 对齐方式、 填充字符等。
#include <iomanip>int num = 42;
std::cout.width(10); // 设置字段宽度为10, 也就是c语言的%m
std::cout.fill("*"); // 填充字符为*
std::cout << std:: left << num << "\n"; // 左对齐输出, 输出结果:
std::cout << std:: right << num << "\n"; // 右对齐输出, 输出结果:

完整的代码

/*************************************************************************> File Name:    demo01.cpp> Author:       小刘> Description:  控制台的输入输出> Created Time: 2025-08-18 10:46:58************************************************************************/
#include <iostream>
#include <iomanip>
#include <string>// 声明使用命名空间
using namespace std;int main()
{// 声明一个字符串的变量string name;int age;cout << "请输入您的名字:";getline(cin,name);cout << "请输入您的年龄:";cin >> age ;double height ;cout << "请输入您的身高(米)";cin >> height;cout << " 个人信息 :" << endl; // cout << " 姓名 :    " << name << " \n";cout << " 年龄 :    " << age  << endl;cout.setf(ios :: fixed);cout.precision(2);cout << " 身高:     " << height << endl;return 0;	
}

内存分区模型

C++ 程序执行时,将内存大方向划分为4个区域

  • 代码区:存放函数体的二进制代码,由操作系统进行管理

  • 全局区:存放全局变量和静态变量以及常量

  • 堆区:由编译器自动分配释放,存放函数的形参值,局部变量等。

  • 栈区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收。

    在这里插入图片描述

内存四区意义:

不同区域存放的数据,赋予不同的生命周期给我们大量的灵活编程。

程序运行前

在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域

代码区:

​ 存放CPU执行的机器指令

​ 代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可

​ 代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令

全局区:

​ 全局变量和静态变量存放在此

​ 全局区还包含了常量区,字符串常量和其他常量也存放在此

​ 该区域的数据在程序结束后由操作系统释放

案例:

/*************************************************************************> File Name:    demo03.cpp> Author:       小刘> Description:  内存分区模型> Created Time: 2025-08-18 14:39:47************************************************************************/
#include <iostream>
#include <iomanip>// 使用std命名空间
using namespace std;// 全局变量:定义在函数外部,默认有初始值是0 \0 NULL
int g_a = 10;
int g_b = 10;// 全局常量:只能赋值一次,一般通过初始值赋值
const int c_g_a = 10;
const int c_g_b = 10;int main()
{// 局部常量:写在函数或者语句块的常量int a = 10;int b = 10;// 打印局部变量地址cout <<  "局部变量a 的地址:" << &a << endl;cout <<  "局部变量b 的地址:" << &b << endl;// 打印全局变量地址cout <<  "全局变量g_a 的地址:" << &g_a << endl;cout <<  "全局变量g_b 的地址:" << &g_b << endl;// 静态变量 存储在数据区static int s_a = 10;static int s_b = 10;// 打印静态变量地址cout <<  "静态变量s_a 的地址:" << &s_a << endl;cout <<  "静态变量s_b 的地址:" << &s_b << endl;cout <<  "全局常量c_g_a 的地址:" << &c_g_a << endl;cout <<  "全局常量c_g_b 的地址:" << &c_g_b << endl;cout <<  "字符串常量的地址:" << &"hello world" << endl;cout <<  "字符串常量的地址:" << &"hello world1" << endl;// 只读常量 | 局部常量const int c_l_a = 10;const int c_l_b = 10;cout <<  "局部常量c_l_a 的地址" << &c_l_a <<endl;cout <<  "局部常量c_l_b 的地址" << &c_l_b <<endl;return 0;
}

在这里插入图片描述

总结

  • C ++中在程序运行前分为全局区和代码区
  • 代码区特点是共享和只读
  • 全局区中存放全局变量、静态变量、常量
  • 常量区中存放const修饰的全局常量和字符串常量

程序执行后

栈区:

​ 由编译器自动分配释放,存放函数的参数值,局部变量等

​ 注意事项:不要返回局部变量的地址,栈区开辟的空间由编译器释放

示例:

int* func()
{int a = 10;return &a; // 返回a 的地址
}int main()
{int *p = func();cout << *p << endl; // 此时p是有值的,存放的就是func中a的地址,但是由于func整体的内存回收所以导致p地址对应的空间不存在,此时这种现象就属于悬挂指针(空悬指针),它是野指针的一种体现。//ststem("pause");return 0;
}

堆区:

​ 由程序员分配释放,若程序员不释放,程序结束后由操作系统回收。

​ 在C++主要利用new在堆区开辟内存。

int func()
{int *a = new int(10); // 等价于 int* a = malloc(sizeof(int));return 0;
}int main()
{int *p = func();cout << *p << endl;return 0;
}

总结:

堆区数据由程序员管理开辟和释放

堆区数据利用new关键字进行开辟内存,利用delete关键字释放内存

new操作符

C++中利用new 操作符在堆区开辟内存。

堆区开辟的内存,由程序员手动开辟,手动释放,释放利用操作符delete

语法:

new 数据类型;
delete 变量;

利用new创建的内存,会返回内存空间的指针。

示例1基本语法

/*************************************************************************> File Name:    demo03.cpp> Author:       小刘> Description:  new 操作符> Created Time: 2025-08-18 15:39:41************************************************************************/
#include <iostream>
#include <iomanip>using namespace std;int* func()
{int *a = new int(10); // 在堆区内存申请4字节的空间,存放一个初始数据10return a;
}
int main()
{int *p = func();cout << *p << endl; //10// 利用delete释放堆区数据delete p ;cout << *p << endl;// 报错,释放的空间不可访问return 0;
}

示例2:开辟数据组

/*************************************************************************> File Name:    demo04.cpp> Author:       小刘> Description:  new操作符,开辟数组> Created Time: 2025-08-18 15:45:51************************************************************************/
#include <iostream>
#include <iomanip>using namespace std;int main()
{int * arr = new int [10];// int(10) 初始化数据位10 ,int[10] 指定数组大小for(int i=0;i<10;i++){arr[i] = i + 100;}for(int i=0;i<10;i++){cout << arr[i] << endl;}delete[] arr;return 0;
}
面试题:new与 malloc的区别?
  1. 联系:

    1.1 new和malloc都可以用来申请堆内存,new运算符内部实现仍然调用了malloc,

    1.2 new和malloc作用于基础数据类型,两者没有区别;

  2. 区别:

    2.1 性质上:new是运算符,malloc是函数

    2.2内存申请上,malloc是要指明申请的内存大小,new会根据目标类型申请内存;

    2.3返回数据类型,malloc只返回void*,new会返回目标类型的指针;

    2.4从底层实现原理上,malloc只负责空间申请,new不仅要空间申请,还要负责对象构造。

    涉及术语:自由存储区自由存储区:用new运算符申请的内存成为自由存储区C++标准库提供的new运算符内部调用了malloc所以此时的自由存储区就是堆区,但C++支持运算符重载,如果我们对new运算符进行了重载,可能在内存申请上就可以从堆区外的其他区域申请,此时的自由存储区就不是堆区了。

引用

引用的基本使用

**作用:**给变量起别名

语法:

数据类型 &别名 = 原名 

示例:

/*************************************************************************> File Name:    demo05.cpp> Author:       小刘> Description:  引用> Created Time: 2025-08-18 15:36:43************************************************************************/
#include <iostream>
#include <iomanip>using namespace std;int main()
{// 定义一个变量int a = 10;// 定义引用int &b = a; // 此时a和b的空间是共享的,也就是b的空间是它的引用的对象a的空间 真正的引用是b & 是一个操作符cout << "a = " << a << endl; // a = 10cout << "b = " << b << endl; // b = 10cout << "a 的地址 " << &a << endl; //a 的地址 0x7f5bdffba4cout << "b 的地址 " << &b << endl; //b 的地址 0x7f5bdffba4b = 100;cout << "a = " << a << endl; // a = 100cout << "b = " << b << endl; // b = 100int aa = 10;int *p = &aa;cout << "aa 的地址 " << &aa << endl; //aa 的地址 0x5c725ff750cout << "p 的地址 " << &p << endl; //p 的地址 0x5c725ff748return 0;
}

引用注意事项

  • 引用必须初始化,否则没有意义
  • 引用在初始化后,不可以改变

引用特点:

①引用不可以改变

②引用对象的值可以改变

示例:

/*************************************************************************> File Name:    demo06.cpp> Author:       小刘> Description:  引用相关案例> Created Time: 2025-08-18 15:51:25************************************************************************/
#include <iostream>
#include <iomanip>using namespace std;int main()
{int a = 10;int b = 20;// int &c; 错误,引用必须初始化int &c = a;// 一旦初始化后,就不可以改变c = b; // 这是赋值操作,不是改变引用cout << "a = " << a << endl; // a = 20cout << "b = " << b << endl; // b = 20cout << "c = " << c << endl; // c = 20return 0;
}

引用做函数参数

**作用:**函数传参时,可以引用的技术让形参修饰实参

**优点:**可以简化指针修改实参

示例

/*************************************************************************> File Name:    demo07.cpp> Author:       小刘> Description:  值传递、地址传递、引用传递> Created Time: 2025-08-18 15:57:19************************************************************************/
#include <iostream>
#include <iomanip>using namespace std;/*
* 1.值传递
*/
void mySwap01(int a, int b)
{int temp = a ;a = b;b = temp;
}/*
* 2.地址传递
*/
void mySwap02(int* a, int* b)
{int temp = *a ;*a = *b;*b = temp;
}/*
* 3.引用传递(C语言不支持)
*/
void mySwap03(int& a, int& b)
{int temp = a ;a = b;b = temp;
}int main()
{int a = 10 ,b = 20; mySwap01(a,b); // 普通的值传递,形参和实参空间是独立的cout << "a = " << a << ", b = " << b << endl;mySwap02(&a,&b); // 地址传递,形参和实参空间是共享的cout << "a = " << a << ", b = " << b << endl;mySwap02(&a,&b); // 引用传递,形参就是使用实参的空间cout << "a = " << a << ", b = " << b << endl;return 0;
}

总结:通过引用参数的效果同按地址传递一样的。引用的语法更清楚简单

引用做函数返回值

**作用:**引用是可以作为函数的返回值存在的。

**注意:**不要返回局部变量的引用。因为会产生野指针。

示例

/*************************************************************************> File Name:    demo08.cpp> Author:       小刘> Description:  > Created Time: 2025-08-18 16:12:13************************************************************************/
#include <iostream>
#include <iomanip>using namespace std;/*
* 返回局部变量引用
*/int& text01()
{
int a = 10;
return a;
}/*
* 返回局部变量引用
*/
int& text02()
{static int a = 20; // 局部变量cout << "a = " << a << endl; return a;
}int main()
{// 不能返回局部变量的引用//int& ref = text01();// cout << "ref = " << ref << endl;  // 这种写法有问题,因为引用的空间已经提前释放了int& ref2 = text02();cout << "ref2= " << ref2 << endl;text02() = 1000;cout << "ref2= " << ref2 << endl;text02();return 0;
}

引用本质

本质:引用的本质在C++内部实现是一个指针常量

示例:

// 发现是引用, 转换为 int* const ref = &a;
void func(int& ref){
ref = 100; // ref是引用, 转换为*ref = 100
}
int main(){int a = 10;//自动转换为 int* const ref = &a; 指针常量是指针指向不可改, 也说明为什么引用不可更改int& ref = a;ref = 20; //内部发现ref是引用, 自动帮我们转换为: *ref = 20;cout << "a:" << a << endl;cout << "ref:" << ref << endl;func(a);return 0;
}

结论:C++推荐用应用技术,因为方便,引用本质是指针常量,但是所有的指针操作编译器都帮我们做了

常量引用

**作用:**常量引用主要用来修饰形参,放置误操作

在函数新参列表中可以加const 修饰形参,防止形参改变实参

/*************************************************************************> File Name:    demo09.cpp> Author:       小刘> Description:  常量引用> Created Time: 2025-08-18 16:55:03************************************************************************/
#include <iostream>
#include <iomanip>using namespace std;// 引用使用场景,通常来修饰形参
void showValue(const int& v)
{//v+= 10 ;等价于 v = v + 10;cout << v << endl;
}int main()
{// int& ref = 10; 引用本身需要一个合法的内存空间// 加入const就可以了, 编译器优化代码: int temp = 10; const int& ref = temp;const int& ref = 10;// ref = 100; // 加入coust 后不可以修改变量cout << ref <<endl; // 10// 函数中利用常量引用防止误操作修改实参int a =20;showValue(a);return 0;
}

思考题:

​ 什么是零拷贝?

函数扩展

函数默认参数

在C++中,函数的形参列表中的形参可以有默认值。

语法:

返回值类型 函数名( 参数 = 默认值) {}

示例:

/*************************************************************************> File Name:    demo10.cpp> Author:       小刘> Description:  > Created Time: 2025-08-18 17:24:22************************************************************************/
#include <iostream>
#include <iomanip>using namespace std;int func(int a, int b = 10,int c = 10)// 如果有对应的实参赋值操作, 形参默认值失效
{return a + b + c;
}int main()
{cout << "rst = " << func(20,20) << endl;// ret = 50 如果有实参, 使用实参数据, 如果无实参, 使用形参默认数据cout << "rst = " << func(100) << endl;// ret = 120return 0;
}

函数占位参数

C++ 中函数的形参列表里有占位参数,用来做占位,调用函数时必须填补该位置

语法: 返回值类型 函数名 (数据类型){}

在现阶段函数的占位参数存在意义不大,但是后面的课程中会用到该技术

示例:

//函数占位参数 , 占位参数也可以有默认参数
void func(int a, int) {cout << "this is func" << endl;
}int main() {func(10,10); //占位参数必须填补system("pause");return 0;
}

函数重载

函数重载概述

**作用:**函数名可以相同,提高复用性

函数重载满足的条件

  • 同一个作用域下(比如同一个文件中)
  • 函数名称相同
  • 函数参数类型不同或者参数个数不同或者顺序不同

**注意:**函数的返回值不可以作为函数重载的条件,也就是说函数重载跟返回值无关。

示例:

// 函数重载需要函数都在同一个作用域下, 比如在同一个文件中
void func()
{cout << "func 的调用! " << endl;
} 
void func(int a)
{cout << "func (int a) 的调用! " << endl;
}
void func(double a)
{cout << "func (double a)的调用! " << endl;
}
void func(int a ,double b)
{cout << "func (int a ,double b) 的调用! " << endl;
} 
void func(double a ,int b)
{cout << "func (double a ,int b)的调用! " << endl;
} //函数返回值不可以作为函数重载条件
//int func(double c, int d)
//{
// cout << "func (double c ,int d)的调用! " << endl;
//}int main() {func();func(10);func(3.14);func(10,3.14);func(3.14 , 10);system("pause");return 0;
}
函数重载注意事项
  • 引用作为重载条件
  • 函数重载碰到函数默认参数

示例:

/*************************************************************************> File Name:    demo11.cpp> Author:       小刘> Description:  函数重载(函数重载注意事项)> Created Time: 2025-08-18 17:37:33************************************************************************/
#include <iostream>
#include <iomanip>using namespace std;/*
* 1.引用作为重载条件
*/
void func(int &a) // 引用不占用任何内存空间,引用的值可变
{cout << "func(int &a) 调用" << endl;
}void func(const int &a) //常量引用,引用的值不可变,一般只读操作
{cout << "func(const int &a) 调用" << endl;
}/*
* 2.函数重载碰到函数默认参数
*/
void func2(int a ,int b = 10)
{cout << "func(int a,int b = 10) 调用"  << endl;
}void func2(int a)
{cout << "func(int a) 调用" << endl;
}int main()
{int a = 10;func(a); 	// 调用无constfunc(10); 	// 调用有constfunc2(10,20); // func2(10);     // 碰到默认参数产生歧义,需要避免return 0;
}
http://www.dtcms.com/a/354242.html

相关文章:

  • 【SystemUI】启动屏幕录制会自动开启投屏
  • 主流配置中心对比
  • 百度测试岗位--面试真题分析
  • JS逆向-反调试绕过事件检测无限Debug篡改猴Hook替换指向匹配修改条件断点
  • 泊松分布知识点讲解
  • Android WPS Office 18.20
  • 【Win软件 - 系统 - 网络】 Windows怎么禁止某个应用联网
  • 洛谷P13849 [CERC 2023] Equal Schedules题解
  • python接口自动化测试报告插件使用
  • CSS扩大点击热区示例
  • 明远智睿 RK3506 核心板:高集成度与强实时性的嵌入式解决方案
  • 【小白笔记】Hugging Face 下载:Git 到镜像网站的
  • 4-3.Python 数据容器 - 集合 set(集合 set 概述、集合的定义、集合的遍历、集合的常用方法)
  • Yolo系列 —— 使用自制数据集训练yolo模型
  • 2021/07 JLPT听力原文 问题一 1番
  • MQTT broker 安装与基础配置实战指南(一)
  • Java:IO流——增强篇
  • anaconda本身有一个python环境(base),想用别的环境就是用anaconda命令行往anaconda里创建虚拟环境
  • 英伟达 spectrum xgs 以太网 的含义和解释
  • 互联网大厂AI面试:从大模型原理到场景应用的深度解析
  • WPF 程序用户权限模块利用MarkupExtension实现控制控件显示
  • 嵌入式分层架构下的AT指令模块设计与实现
  • 使用Nginx搭建图片传输服务:配置与优化指南
  • Content-Type是application/x-www-form-urlencoded表示从前端到后端提交的是表单的形式
  • 微服务的编程测评系统17-判题功能-代码沙箱
  • 除自身以外数组的乘积是什么意思
  • 算法刷题常见错误
  • Linux 打包及压缩基础知识总结
  • 车间生产管理遇到的问题及改善方案有哪些?
  • 在 Windows 上部署 Go 语言开发环境