C++ 入门基础

news2024/11/17 23:32:10

✨个人主页: Yohifo
🎉所属专栏: C++修行之路
🎊每篇一句: 图片来源

  • The longest way must have its close,the gloomiest night will wear on a morning.

    • 最长的路也有尽头,最黑暗的夜晚也会迎来清晨。

    多彩天空


文章目录

  • 📘前言
  • 📘正文
    • 📖初识C++
      • 🖋️C++起源
      • 🖋️C++关键字
      • 🖋️C++第一个程序
    • 📖命名空间
      • 🖋️展开方式
    • 📖缺省参数
      • 🖋️注意事项
    • 📖函数重载
    • 📖引用
      • 🖋️引用特性
      • 🖋️常引用
      • 🖋️使用场景
      • 🖋️小结
    • 📖内联函数
    • 📖auto关键字
    • 📖范围for
    • 📖nullptr指针空值
  • 📘总结


📘前言

C++C语言 的超集,是一门在 C语言 基础上发展起来的语言,C++ 很强大,如今 C++ 已是一个多重范型编程语言,主要包含四部分:CObject-Oriented C++Template C++STL,因此我们一般将 C++ 看作一个语言联邦,显然 C++ 的内容很丰富,也比较难学,但当我们掌握后,它将称为一把利刃

C++ 摘得 TIOBE 2022 年度编程语言桂冠
C++摘得桂冠


📘正文

📖初识C++

先简单了解下 C++ 的起源

C++之父本贾尼

C++祖师爷—本贾尼·斯特劳斯特卢普

🖋️C++起源

C语言 是结构化和模块化的语言,适合处理较小规模的程序。对于复杂的问题,规模较大的程序,需要高度的抽象和建模时,C语言 则不合适。为了解决软件危机, 20世纪80年代, 计算机界提出了OOP(object oriented programming:面向对象)思想,支持面向对象的程序设计语言应运而生

总结:C语言 无法满足大型软件的开发需求

无所谓,祖师爷会出手

1979年,贝尔实验室的本贾尼等人试图分析 UNIX 内核的时候,试图将内核模块化,于是在 C语言 的基础上进行扩展,增加了类的机制,完成了一个可以运行的预处理程序,称之为 C with classes

1982年,本贾尼博士在 C语言 的基础上引入并扩充了面向对象的概念,发明了一种新的程序语言。为了表达该语言与 C语言 的渊源关系,命名为 C++ 因此:C++ 是基于 C语言 而产生的,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行面向对象的程序设计。

在本贾尼博士的不断修修改改下,一门新的编程语言 C++ 就诞生了

1998年,C++ 标准第一个版本发布,绝大多数编译器都支持,得到了国际标准化组织(ISO)和美国标准化协会认可,以模板方式重写 C++ 标准库,引入了 STL (标准模板库)

2011年,C++ 11标准发布,增加了许多特性,使得 C++ 更像一种新语言,比如:正则表达式、基于范围for循环、auto关键字、新容器、列表初始化、标准线程库等

2020年,C++ 引入了许多新的特性,比如:模块(Modules)、协程(Coroutines)、范围(Ranges)、概念(Constraints)等重大特性,还有对已有特性的更新:比如Lambda支持模板、范围for支持初始化等

由此可见,C++ 是一门更新周期长、内容丰富的编程语言,如今大多数公司主要实用标准为 C++98C++11 ,因此我们现阶段还不需要掌握最新标准内容,从 C++ 入门基础开始,稳扎稳打,争取学好 C++

来自陈皓大佬的吐槽
21天学懂C++

🖋️C++关键字

C++ 兼容 C语言,因此 C语言 中的所有32个关键字在 C++ 中均可以使用,当然 C++ 在此基础上新增了31个关键字,使得 C++ 中的关键字数达到了63,当然这么多关键字现在没必要全部看懂,在学习后面知识时会用到
C++中的关键字

🖋️C++第一个程序

江湖规矩,学习 C++ 首先少不了 Hello World!

#include<iostream>	//IO流头文件
using namespace std;	//全局展开std命名空间

int main()
{
	// cout 是输出函数
	// << 流插入运算符,配合 cout 使用
	// endl 换行符,相当于 \n
	cout << "Hello World!" << endl;
	return 0;
}

Hello World!
向世界打个招呼后,我们就可以正式开始 C++ 的修行之路了


📖命名空间

命名空间是我们接触的第一个 C++ 特性,当然其他高级语言也支持

背景

  • 在使用 C语言 时,我们自己定义的名字可能和库函数起冲突,或者在同一个项目组中,多人定义的名字起冲突

此时我们只有改名字这一条路可选,显然祖师爷本贾尼对于这种方法很不满, 于是他想出来这种解决方法

  • 通过不同的命名空间将 变量/函数 限定使用,即使存在两个同名变量,只要相应空间找对了,也不会起冲突
#include<iostream>	//IO流头文件
using namespace std;	//全局展开std命名空间

//命名空间
namespace AA
{
	int num = 10;
}

namespace BB
{
	int num = 24;
}

int main()
{
	//不同命名空间内的同名 变量/函数 不冲突
	cout << AA::num << endl;
	cout << BB::num << endl;
	return 0;
}

命名空间

🖋️展开方式

此时我们就能看懂下面这行代码了

using namespace std;	//全局展开std命名空间

它的作用是展开 std 这个命名空间,即库函数,只有展开后,我们才能正常使用 cout
这种展开方式叫做 全局展开,除了 全局展开 外,还有 部分展开域作用限定符展开

全局展开

using namespace 命名空间;	//全局展开覆盖范围为整个程序
//比如
using namespace AA;	//全局展开AA这个命名空间,可以在任意位置使用AA中的变量/函数

部分展开

using 命名空间::待使用变量/函数;
//比如
using AA::num;	//只展开AA中的变量num,此时可在任意位置使用AA中的变量num

域作用限定符

//需要使用时
cout << 命名空间::待使用变量/函数 << endl;	//需要使用时展开
//比如
std::cout << AA::num << std::endl;	//这个就是使用时展开
//注意:假设 :: 左边为空,如 ::num 这种情况,会去全局范围内查找变量
//num,如果没有找到,就会报错

三种方式各有好坏,使用场景有所不同

  • 当我们日常写小程序时,可以使用 全局展开 的方式,因为不受其他人干扰,也不会干扰其他人
  • 其他场景中,推荐使用 部分展开 + 域作用限定符,频繁使用的对象通过 部分展开,使用频率较少的对象直接使用 域作用限定符 就行了
  • 原因: 如果随意使用全局展开,那么命名空间就没有存在的意义了

注意:

  • 命名空间支持嵌套使用
  • 如果出现同名的命名空间,编译器会将其合并,可能会引起冲突
  • 命名空间是在编译查找时启用

📖缺省参数

祖师爷在 C++ 中设计了缺省参数这个概念,使得函数在没有参数传递时也可以按其他方式运行

缺省参数

  • 在函数声明时,为形参设定初始值,当有实参传入时,使用实参;如果没有实参传入,则启用初始值
  • 缺省参数就像是现实中的舔狗、备胎,做好随时被需要的准备
#include<iostream>	//IO流头文件
using namespace std;	//全局展开std命名空间

//在函数声明时给形参设定初始值
void print(int val = 999)
{
	if (val == 999)
		cout << "缺省参数已启用 val 值为:";
	else
		cout << "缺省参数未启用 val 值为:";

	cout << val << endl;
}

int main()
{
	print(100);
	print();	//设有缺省参数的函数,可以不传参数
	return 0;
}

缺省参数
缺省参数的出现使得函数运行多了一种可能,实际运用场景如:在 初始化时,设定缺省参数值为4,即默认大小为4,假若用户不传参数,则按4来初始化 大小;若传递了参数,则按实参初始化 大小
缺省参数

🖋️注意事项

缺省参数很实用,但也要慎用

缺省参数有很多使用规则:

1、只允许从右到左依次连续缺省,不得出现跳跃缺省

//正确用法
void test(int a, int b = 2, int c = 3);	//从右至左,连续缺省

//错误用法
void test(int a = 1, int b, int c);	//非从右至左缺省
void test(int a, int b = 2, int c);	//跳跃缺省,非法

2、调用时,实参依次从左往右传递

//正确用法
test(4,5,6);	//不启用缺省值,a = 4,b = 5, c = 6
test(5,6);	//启用缺省参数 c,a = 5, b = 6, c = 3

//错误用法
test();	//此时必须传一个参数,因为参数 a 不是缺省参数
test(1,2,3,4);	//参数传多了

3、声明和定义中不能同时出现缺省参数,只能在声明中出现

//test.h
//声明时缺省
void test(int a = 10);	

//test.c
//定义时不必再缺省
void test(int a)
{
	cout << a << endl;
}

4、C语言不支持缺省参数

void test(int a = 10);	//C语言实现会报错

📖函数重载

C语言 不允许两个函数名字相同,比如函数 Add 只能适用于一种数据类型,在 C++ 中支持函数重载,即在参数不同(包括类型不同或顺序不同)的前提下,允许同时存在多个同名函数

//C语言
int Add(int x, int y);
double Add(double x, double y);	//此时会报错,两个函数名冲突

//C++
int Add(int x, int y);
double Add(double x, double y);	//正常编译,即使函数名都是Add,但在C++中编译器能分清两者

原因: C++中引入了新的函数名修饰规则,比如对于两个Add函数来说,Linux中会分别修饰为 _3Addii 与 _3Adddd,显然两者是不同的;而对于C语言来说两个函数名修饰后都为 Add

我们可以在 Linux 环境下,通过指令 objdump -S 可执行程序 查看函数名修饰情况

命名修饰规则
函数名修饰后,后序并入符号表,链接时只要函数修饰名不冲突,就可以正常链接
Linux 中对于函数名的修饰规则比较简单,而 Windows 中则比较复杂,如在 VS 中,上述函数名修饰为 ?Add@@YAHHH@Z 过于复杂了

下面是重载的各种情况

//假设存在函数 func
void func(int* pa, int len);	//修饰为 _4ZfuncPii 指针需加P

//正确的重载情况,只要修饰后的函数名不冲突,就能构成重载
void func(int& pa, int len);	//修饰为 _4ZfuncRii 引用需加R
int func(int len, int* pa);	//修饰为 _4ZfunciPi
char* func(int* pa);	//修饰为 _4ZfuncPi

//错误的重载情况
int func(int* pb, int n);	//修饰为 _4ZfuncPii 冲突

void testc(int a, int b);	//修饰为 _4Ztestcii
void testc(int b, int a);	//修饰为 _4Ztestcii 冲突

注意: 返回值不纳入函数名修饰中,假若加入,函数调用时就会出现混乱,因此返回值不同并不构成函数重载


📖引用

引用是一个很好用的工具,它有指针指向同一块数据的能力,同时它不像指针那样危险、复杂,换句话说,引用是指针改进版,在后续学习中,有 80% 的场景都会使用引用而非指针

int a = 10;

int* pa = &a;	//指针
int& ra = a;	//引用

引用的底层实现仍然是指针

指针和引用

引用相当于给变量取别名

比如在我们日常生活中,马铃薯/山药蛋/洋芋/洋番芋/薯仔/Potato等等都表示 土豆,不同地区叫法不同,换句话说,土豆 在全国各地有很多个引用,只要表示对了,都是指 土豆

上面代码段中的 raa 都表示同一块空间,而 *paa 也表示同一块空间;可以简单把引用理解为一个智能版指针,会自动解引用,使用起来更方便

🖋️引用特性

引用有很多使用特性,即使用规范,使得引用更加安全

  1. 引用必须初始化,当一个引用变量被创建时,必须存在其所代表的变量
  2. 一个变量可以存在多个引用,就像 土豆 可以有多个别名
  3. 当引用初始化后,无法再代表其他变量,每个引用一生只为一人
  4. 不存在多级引用,当 引用b 代表 引用a 时,实际上就是在代表 引用a 所代表的变量 a
char a = 'A';
char b = 'B';

//1、引用必须初始化
char& ra = a;	//正确
char& rx;	//错误,必须初始化

//2、一个变量可以有多个引用
char& ra = a;
char& rra = a;
char& rrra = a;	//没有问题,一个变量允许存在多个引用

//3、引用无法改变指向
char& ra = a;
char& ra = b;	//错误,引用一旦确立后,就无法再改变其指向
ra = b;	//这个没问题,实际结果为 a = 'B' 即将 b 的内容赋值给 a

//4、不存在多级引用
char& ra = a;
char&& b = ra;	//非法,不存在多级引用
char& b = ra;	//合法,实际结果为 char& b = a;

注意: 引用不能像指针那样随意使用,引用也不存在指针多级指向的功能

比如下图这种情况对于引用来说是不存在的
指针

🖋️常引用

对于指针和引用来说,存在权限问题,因为指针和引用具有直接修改原数据的能力

众所周知,对于程序来说,存在几个区域:栈、堆、静态区等等,我们使用的常量位于数据段或代码段中,常量具有可读不可修改的特性,当我们使用普通指针或引用指向常量数据时,会引发错误
常引用问题

int main()
{
	const int a = 10;	//此时a为常变量,具有常量属性

	const int* pa = &a;	//正常
	const int& ra = a;	//正常
	return 0;
}

解决方法也很简单,将指针或引用改为只读权限,就能正常指向常量了(权限平移)

🖋️使用场景

引用主要有以下几个使用场景

1、做参数

void swap(int& ra, int& rb)
{
	//有了引用之后,不需要再解引用,也能达到指针的效果
	int tmp = ra;
	ra = rb;
	rb = tmp;
}

2、做返回值

#include<iostream>
using namespace std;

int arr[10] = {0};	//数组为全局变量

int& getVal(int pos)
{
	//返回数组指定位置的值
	return arr[pos];
}

int main()
{
	for(int i = 0; i < 10; i++)
	{
		//借助引用,可以直接通过返回值修改数组中的值
		getVal(i) = i * 10;
		cout << arr[i] << " ";
	}
	cout << endl;
	return 0;
}

引用
当引用做返回值时,接收到的变量就是函数返回时的本体,比如全局数组 arr ,此时对返回值做出修改,就是在改变数组 arr

引用返回很强大,但也不能随便使用,引用返回一般用于生命周期较长的变量,即函数结束后不被销毁的变量,如果使用生命周期短的变量作为引用返回值,那么结果是未定义的

int& func(int n)
{
	int val = n;
	return val;	//结果未定义
}

//val是函数 func 中的局部变量,当函数结束后,变量就被销毁了
//此时可能得到正确的结果(编译器未清理),也可能得到错误的结果(编译器已清理)
//因此说结果是未定义的
//可以看到下图中相同语句出现两种结果

结果未定义

引用返回原理:
引用返回原理
之前我们一直都是走的临时变量那条路,现在有了引用后,在使用生命周期较长的变量时,就可以考虑使用引用返回来提高效率

性能对比1w数据量10w数据量
普通值返回14ms1753ms
引用返回0ms1ms

🖋️小结

引用是比较重要的特性,需要小结一下:

  • 引用在概念上是给变量取别名,而指针是新开一块空间指向变量
  • 引用必须初始化,指针可以不初始化
  • 引用无法改变指向,指针可以
  • 不存在空引用,但存在空指针
  • 引用大小为所代表变量的大小,而指针大小为 4/8 字节
  • 引用+1等价于变量+1,指针+1则表示指向位置向后偏移一个单位
  • 引用不需要解引用,指针使用前需要解引用
  • 引用使用起来更安全、更方便

以后涉及需要改变原变量值时,优先考虑使用引用,特殊场景下,仍然需要使用指针

引用与指针互不冲突,两者都有自己适用的领域,比如在实现链表时,必须使用指针,因为引用无法改变指向,而链表需要频繁的进行改链操作


📖内联函数

内联函数主要是为了替代宏函数,因为宏函数存在很多坑,并且在某些场景下使用复杂

#define ADD(x, y) ((x) + (y))	//通过宏函数实现ADD,比较复杂、麻烦

除了使用复杂外,宏还存在以下缺点:

  • 不能进行调试,宏是直接进行替换的
  • 没有类型安全检查

在书籍《Effective C++》 中,作者建议

  • 使用 constenum 替换宏定义的常量
  • 使用内联函数 inline 替换宏函数
  • 总之,宏很危险,需要少用

所谓内联函数就是在函数实现前加上 inline 修饰,此时函数会被编译器标记为内联函数

//此时的 Add 函数就是一个内联函数
inline int Add(int x, int y)
{
	return x + y;
}

内联函数特点:

  • Debug 模式下,函数不会进行替换,可以进行调试
  • Realse 模式下,函数会像宏函数一样展开,提高程序运行速度
  • 内联函数弥补了宏函数的不足,同时吸收了宏函数速度快的优点

内联函数
内联函数可以全面替代宏,当然使用时也需要注意

  • 频繁使用内联函数,编译出来的可执行程序会更大,因为代码会变多,但运行速度更快
  • 调用内联函数时,是否展开取决于编译器,如果内联函数展开后会影响性能,那么编译器有权不展开内联函数
  • 内联函数适用于代码行数较少,且被频繁调用的小函数
  • 内联函数不建议声明和定义分开,因为内联函数不进入符号表,因此可能产生链接错误,推荐在声明时就顺便将函数定义,头文件展开时,将内联函数一起包含

📖auto关键字

这个是 C++11 中的新特性,auto 关键字能直接识别目标变量类型,然后自动转换为相应类型

int a = 10;
int* b = &a;

auto aa = a;	//此时 aa 为 int
auto bb = b;	//此时 bb 为 int*

除了自动识别外,我们还可以指定转化类型

int a = 10;

auto* pa = a;	//指定 pa 为 int*
auto& ra = a;	//指定 pa 为 int&

在后期学习中,某个变量类型可能非常长,此时可以利用 auto 自动识别类型

auto 支持一行声明多个变量,当然类型得统一

auto a = 1, b = 2, c = 3;	//合法,类型统一
auto a = 1, b = 2.2;	//非法,类型不统一

注意: auto 不能用于数组,auto 也不能当作参数类型


📖范围for

这个也是 C++11 中的新特性,是一个语法糖,范围 for 循环拥有自动拷贝、自动判断范围、自动结束等特点,使用起来很方便

#include<iostream>
using namespace std;

int main()
{
	int arr[] = {1, 2, 3, 4, 5};

	//范围 for 循环
	for(auto val : arr)
	{
		cout << val << " ";
	}
	cout << endl;
	return 0;
}

输出结果
范围 for 配上 auto 自动识别类型,写出来的循环很简单,在加上引用,使得我们可以轻而易举的给数组赋值

#include<iostream>
using namespace std;

int main()
{
	int arr[] = {1, 2, 3, 4, 5};

	//范围 for 循环
	//配合引用修改原数组值
	for(auto& val : arr)
	{
		val *= 2;
		cout << val << " ";
	}
	cout << endl;

	return 0;
}

引用

注意: 范围 for 遍历数组时,数组大小必须确定,迭代的对象要实现 ++ 和 == 的操作


📖nullptr指针空值

这个是 C++11 中新增的补丁,因为在设计 C++ 时,指针空值 NULL 出了点问题,NULL 可能被编译器直接识别为 0 而非 void*

#include<iostream>
using namespace std;

void func(int)
{
	cout << "参数为整型 0" << endl;
}

void func(void*)
{
	cout << "参数为指针 void*" << endl;
}

int main()
{
	func(0);
	func(NULL);
	return 0;
}

结果
可以看到,NULL 并没有被识别为指针空值,因此委员会推出了 nullptr 这个补丁,专门用于给指针置空
nullptr
注意:

  • nullptr 是作为关键字加入的,不需要头文件
  • nullptrvoid* 的大小一致
  • 在后续学习中,为了确保程序的健壮性,建议指针置空使用 nullptr 而非 NULL

auto、范围for、nullptr 这些都是 C++11 中的新特性,较老的编译器可能不支持


📘总结

以上就是关于 C++ 入门基础的全部内容了,我们从 C++ 的诞生开始,认识了 C++ 为弥补 C语言 缺陷所做出的改动,也学习了 C++ 中的各种新特性,如 引用内联auto等等;C++ 很强大,学习周期很长,但我相信锲而不舍,金石可镂,再高的山峰也有人成功登顶,C++ 的修行之路才刚刚开始,我们已充满信心

如果你觉得本文写的还不错的话,期待留下一个小小的赞👍,你的支持是我分享的最大动力!

如果本文有不足或错误的地方,随时欢迎指出,我会在第一时间改正


相关文章推荐
作为C++系列的第一篇文章,没啥可推荐的,就简单弄个投票环节吧

感谢支持

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/195377.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

擅长做财务分析的BI软件有哪些?

财务分析是企业数据分析中的一个重要板块&#xff0c;所以基本上BI软件都能做基础的财务数据分析&#xff0c;比如说帆软、永洪、思迈特等&#xff0c;但要说到系统化地、高效地做企业财务分析&#xff0c;还是要看奥威BI软件。 之所以说BI财务分析软件看奥威BI&#xff0c;是…

【万文全解】Java集合源码解析【HashMap】【ArrayList】【JDK源码集合部分】

Java集合源码解析 本文主体部分是作者跟着B站韩顺平老师的课程总结而来&#xff0c;中间穿插自己的理解还有网上各类优质解答 第一节&#xff1a;集合介绍与集合体系图 集合与数组对比&#xff08;引入集合的目的&#xff09; 数组&#xff1a; 长度必须指定&#xff0c;一…

javaEE 初阶 — TCP 流套接字编程

文章目录1. TCP 流套接字1.1 ServerSocket API1.2 Socket API1.3 TCP中的长短连接2. TCP 版本的回显服务器3. TCP 版本的回显客户端4. 如何给多个客户端提供服务1. TCP 流套接字 TCP 不需要一个类&#xff1b;来表示 “TCP” 数据报。 TCP 不是以数据报为单位进行传输的&#x…

拉伯配资“十年一剑”硕果累累 我国注册制改革迈入新征程

从2013年党的十八届三中全会明确提出“推动股票发行注册制变革”&#xff0c;到首届进博会上宣告科创板试点注册制&#xff0c;再到本年2月1日全面施行股票发行注册制变革正式发动&#xff0c;十年风雨兼程&#xff0c;我国注册制逐渐从“试点”走向“全面”。 2013年11月&…

编译链接过程详解

写在前面&#xff1a; 大家都知道&#xff0c;我们在编译器中建好一个**.c或.cpp 文件**&#xff0c;经过编译之后就可以运行了&#xff0c;也就是说我们写的.c 文件最后会变成一个可执行程序&#xff0c;那么 .c 或者 .cpp 文件是如何变成一个可执行程序的呢&#xff1f; 主要…

Vue计算属性和监视属性

目录 计算属性computed 监事属性 深度监视 计算属性computed 计算属性: 定义&#xff1a;要用的属性不存在&#xff0c;要通过已有属性计算得来 2、原理&#xff1a;底层借助了Object.defineproperty方法提供的getter和setter 3、get函数什么时候执行&#xff1f; 1、初…

移动硬盘修复的有效方法,恢复移动硬盘的数据这么做!

硬盘是计算机中的存储设备&#xff0c;是非常重要的部分。当硬盘发生故障&#xff0c;很可能会导致我们电脑里面的数据丢失。所以移动硬盘发生故障&#xff0c;我们一定要想办法修复它。 有没有什么操作方法&#xff0c;我们自己也可以简单进行&#xff1f;移动硬盘修复其实也…

mariadb数据库删除恢复过程

不作不死&#xff0c;不小心使sqlyog导数据选错服务器。把生产机的数据全部删除了。可怕的数据没有做其他过多的备份&#xff0c;只是每天自动crontab 备份。该怎么办呢&#xff1f;头脑一片空白。快&#xff0c; 赶紧看看日备份有没有。马上切换到备份目录&#xff0c;喜出望外…

构建指标体系是一套数据分析的框架,比如看哪些指标,这些指标变化了就会反映什么问题,是这样的吗?

指标体系是指由若干个反映企业业务运营特征的相对独立又相互联系的统计指标所组成的有机整体。近年来&#xff0c;各类企业逐渐认识到业务指标的重要性&#xff0c;从管理者们长期关注的企业绩效考核&#xff0c;到用来体现信息化水平的数据可视化大屏&#xff0c;其背后都离不…

【IoT】寻光智能车与循迹智能车

1、寻光智能车 功能说明 智能寻光小车&#xff0c;智能识别光线强弱&#xff0c;实现小车永远向光最强的地方行走&#xff0c;到光源处小车自动停止。基本车体为三轮、二驱、双层机构。主控芯片采用最常用的51单片机&#xff1b; 驱动采用L9110驱动芯片驱动两个减速直流电机…

Veeam ONE v12 发布 (含下载) - 面向所有工作负载的 IT 监控解决方案

Veeam Availability Suite v12 请访问原文链接&#xff1a;https://sysin.org/blog/veeam-one-12/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;www.sysin.org 概述 保持全面可视性和控制力&#xff0c;以高效执行管理、优化、计划和…

域渗透漏洞

一、域内提权漏洞 (CVE-2021-42287和CVE-2021-42278) 1.1 漏洞介绍 1.1.1 CVE-2021-42278 主机账户的名称尾部应该有一个 $(即 sAMAccountName 属性)&#xff0c;但是域控对此属性并没有任何验证来确保是否带有 $&#xff0c;这允许攻击者模拟域控主机账户。 1.1.2 CVE-2021-42…

python带你制作自动答题程序,速度超越98%人

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 目录前言环境使用:模块使用:自动答题思路步骤:代码展示尾语 &#x1f49d;环境使用: Python 3.8 –> 解释器 <执行python代码> Pycharm –> 编辑器 <写python代码的> 模块使用: import requests —&g…

Springboot_vue摄影作品图片展示交流平台

前后端通讯一般都是采取标准的JSON格式来交互。 前后端分离 的核心思想是前端页面通过 ajax 调用后端的 restuful api 进行数据交互&#xff0c;而 单页面应用&#xff08;single page web application&#xff0c;SPA&#xff09;&#xff0c;就是只有一张页面&#xff0c;并在…

https解决方案-利用keytool生成证书

https解决方案 1:什么是HTTPS&#xff1f; HTTPS其实是有两部分组成&#xff1a;HTTP SSL / TLS&#xff0c; 也就是在HTTP上又加了一层处理加密信息的模块&#xff0c;并且会进行身份的验证。 2:什么是自签名证书&#xff1f; 就是自己生成的证书&#xff0c;并不是官方…

计算机中的大小端存储

在讲C语言的时候&#xff0c;有讲到大小端的内容&#xff0c;这里呢对大小端的相关内容进行了整理&#xff0c;有需要的可以参考一下&#xff01; 大端和小端来自一个小故事&#xff1a;端模式(Endian)的这个词出自Jonathan Swift书写的《格列佛游记》。这本书根据将鸡蛋敲开的…

mysql导致索引失效的常见情况以及命名规范索引计划分析

1、失效的情况 1.前导模糊查询不能利用索引(like ‘%XX’或者like ‘%XX%’) 假如有这样一列code的值为’AAA’,‘AAB’,‘BAA’,‘BAB’ ,如果where code like %AB’条件&#xff0c;由于前面是 模糊的&#xff0c;所以不能利用索引的顺序&#xff0c;必须一个个去找&#xf…

虚拟机的Linux安装redis

1&#xff0c;下载redis 可以去官网下载压缩包 2&#xff0c;环境准备 我看很多文章都说要安装yum&#xff0c;但是在终端界面一直都是安装失败&#xff0c;后面才知道我的虚拟机是Ubuntu版本&#xff0c;而Ubuntu版本一般不使用yum命令&#xff0c;一般都是使用apt-get命令…

RANSAC: Random Sample Consensus

目录RANSAC算法基本思想和流程迭代次数推导参考RANSAC RANSAC(RAndom SAmple Consensus,随机采样一致)算法是从一组含有外点(outliers)的数据中正确估计数学模型参数的迭代算法。“外点”一般指的的数据中的噪声&#xff0c;比如说匹配中的误匹配和估计曲线中的离群点。所以&a…

电脑黑屏却开着机是怎么回事?解决黑屏的快捷方法

我们经常会用到电脑&#xff0c;但是你真的了解电脑相关知识吗&#xff1f;遇到比较复杂的电脑问题&#xff0c;你是否会手足无措&#xff1f;电脑黑屏却开着机这是什么原因造成的&#xff0c;我们有什么好办法恢复黑屏的电脑吗&#xff1f; 本文针对电脑黑屏却开着机的情况&a…