《深入探究:C++ 在多方面对 C 语言实现的优化》
目录
- 一、C++ 在 C 上进行的优化
- 二、C++ 关键字(C++ 98)
- 三、C++ 的输入输出
- 1. cin 和 cout 的使用
- 2. cin、cout 和 scanf()、printf() 的区别
- 三、命名空间
- 1. 命名空间的使用
- 2. 嵌套命名空间
- 3. 在多个头文件中使用相同的命名空间
- 四、函数缺省值
- 1. 缺省值的使用
- 2. 缺省值使用的注意事项
- 五、函数重载
- 1. 函数重载的使用
- 2. 为什么函数返回类型不同不算函数重载?
- 六、引用
- 1. 引用的使用
- 2. 常量引用
- 3. 常量引用和普通引用的区别
- 5. 引用传参
- 6. 引用的注意事项
- 七、内联函数
- 1. 内联函数的使用
- 2. 内联函数的注意事项
- 3. 宏的优缺点?C++ 有哪些技术替代宏?
- 八、auto 关键字
- 1. auto 关键字的使用
- 2. auto 关键字使用的注意事项
- 九、基于范围的 for 循环
- 1. 范围 for 的使用
- 2. 范围 for 的使用条件
- 十、空指针 nullptr(C++11)
一、C++ 在 C 上进行的优化
C++ 在 C 的基础上加入了面向对象编程、泛型编程和许多有用的库。弥补了 C 语言的不足,并对 C 语言不合理的地方进行优化,使其更加适应当前时代的需求和发展。
由于 C++ 兼容大部分的 C,所以可以在 C++ 中混合使用 C 来进行编写代码,如使用 printf() 函数和 scanf() 函数。
二、C++ 关键字(C++ 98)
下面的关键字看看就行,不用背,用的多了就记住了,很多都是 C 语言学过的。
三、C++ 的输入输出
在 C++ 中,输入输出被看成输入流和输出流,使用 iostream 库中的 istream 和 ostream 分别表示输入流和输出流。标准输入就可以理解为把键盘敲击输入的信息放入输入流中,而标准输出就可以理解为把输出的信息放入输出流中,随着输出流显示到显示器上。一个流就是一个字符。术语 “流” 的意思是,随着时间的推移,字符是顺序生成或者消耗的。
而标准库定义了名为 cin 的 istream 类的对象和名为 cout 的 ostream 类的对象并通过流插入运算符(<<)和流提取运算符(>>)用来处理标准输入和标准输出。cin 和 cout 均可智能识别其后数据的类型。
1. cin 和 cout 的使用
首先,使用 cin 和 cout 输入输出对象需要完成下面两步:
1)包含 iostream 库,因为 istream 类和 ostream 类包含在 iostream 库中。
2) 使用标准命名空间 std,或者单独声明 cin 和 cout。
// 头文件
#include <iostream>// 使用标准命名空间 std
using namespace std;int main()
{int i = 0;double d = 0;char c = 0;// 输入cin >> i; // 单个变量输入cin >> d >> c; // 多个变量连续输入// 输入cout << "i = " << i << endl;cout << "d = " << d << endl;cout << "c = " << c << endl;return 0;
}
在上述代码中,流提取运算符(>>)搭配 cin 使用,流插入运算符(<<)搭配 cout 使用,后面跟需要输入和输出的数据即可。也可以连续输入和输出,因为 cin 和 cout 在输入和输出完成第一个数据之后会返回一个类对象的引用。连续输入只要中间间隔空白(空格、制表符和换行符)即可。
endl 是 C++ 的操纵符,把它写入标准输出流的作用是换行并刷新缓冲区。
代码运行结果如下:
2. cin、cout 和 scanf()、printf() 的区别
1)cin、cout 是类对象,而 scanf() 和 printf() 是函数;
2)cin、cout 使用流插提取运算符(>>)和流插入运算符(<<)来进行输入和输出,scanf() 和 printf() 使用参数传递的方式来进行输入和输出;
3)cin、cout 适用于非格式化输入和输出,scanf() 和 printf() 适合格式化输入和输出。
三、命名空间
当我们包含库中的头文件时,由于该头文件中的内容过多,很容易和我们自己命名的名称冲突。当我们和他人一起编写大型项目时,我们和他人命名的名称也很容易冲突。
上面的问题放在 C 语言中,只能使用不同的名称,而在 C++ 中可以通过使用关键字 namespace 创建命名空间来解决。
1. 命名空间的使用
创建命名空间的格式为:namespace 名称 { … }
// 头文件
#include <iostream>// 使用标准名称空间
using namespace std;// 创建命名空间 qcx
namespace qcx
{int a = 3;// 交换函数void Swap(int* a, int* b){int tmp = *a;*a = *b;*b = tmp;}
}// 交换函数
void Swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}int a = 2;int main()
{int a = 1;cout << "局部变量: " << a << endl;cout << "全局变量: " << ::a << endl;cout << "命名空间: " << qcx::a << endl;return 0;
}
上述代码运行结果如下:
可以看到,代码正常运行。且在上述代码中,出现了三个同名变量 a,和两个一模一样的函数,倘若这放在 C 语言中,编译阶段就已经报错了。
第一条 cout 语句中的变量 a 是局部变量,当全局变量名和局部变量名冲突时,局部优先,且编译器在使用变量名时,会先在局部查找,然后在全局查找,不会主动访问命名空间的内容。第二条 cout 语句中的变量 a,使用 C++ 中的作用域解析运算符(::),当该运算符的左侧为空白时,默认访问全局变量。第三条 cout 语句,使用作用域解析运算符(::)显示访问命名空间 qcx 中的变量 a。
名称冲突是在同一个作用域中出现了同名的变量或者函数,而命名空间的作用是开辟一个新的作用域,所以上述代码中的三个 a 变量的作用域分别为:局部作用域,全局作用域,命名空间作用域,所以不会造成命名冲突。
(1)为什么包含头文件 iostream 后还需要使用标准命名空间 std ?
在学习 C 语言的时候,包含的头文件在编译阶段就直接展开了,且该头文件包含的内容可以直接使用。
但是,C++ 把标准库中的内容全部封装到了标准命名空间 std 中,比如现在包含头文件 iostream 相当于包含了如下内容:
namespace std
{
iostream 文件的内容
}
就像我们前面说的,编译器是不会主动访问命名空间中的内容的,所以如果仅仅只包含该头文件,我们是不能去使用里面的工具的。
而语句 using namespace std; 的作用是把外面的 namespace std 去掉,把里面的内容显示出来,也就相当于学习 C 语言时的包含头文件。
但是,如果直接使用 using namespace std,不就相当于命名空间白用了?把头文件中的内容全部展开和 C 语言不就没有区别了?所以,C++ 还提供了把命名空间里面的单个工具展开,如:using std::cout;,把 cout 类对象放入全局,这样我们就可以使用 cout 工具,且不用担心名称冲突了。
当然如果不嫌麻烦,也可以显示访问命名空间 std,如:std::cout << qcx::a << std::endl;。
(2)命名空间中可以存放变量、结构体、函数、类等内容
2. 嵌套命名空间
嵌套命名空间就是一个命名空间里面再包含命名空间,和嵌套循环一个意思。这个很容易理解,比如我们制作一款游戏,那么把战斗模块和数值模块分的代码放入各自的命名空间,然后战斗模块的每个组的代码放入各自的命名空间,最后每个组的成员的代码又放入各自的命名空间。
具体效果类似如下代码:
// 游戏
namespace game
{// 战斗模块namespace Battle{// a 组namespace a{// 小王namespace wang{// 代码...}// 小张namespace zhang{// 代码...}}// b 组namespace b{// 小王namespace wang{// 代码...}// 小张namespace zhang{// 代码...}}}// 数值模块namespace Numerical{// a 组namespace a{// 小王namespace wang{// 代码...}// 小张namespace zhang{// 代码...}}// b 组namespace b{// 小王namespace wang{// 代码...}// 小张namespace zhang{// 代码...}}}
}
如果需要访问战斗模块 a 组小王的变量 age,可以使用如下方法:
1)using Game::Battle:: a::wang::age;
2)using namespace Game::Battle:: a::wang;
(上面 a 前面加个空格是CSDN防止格式化)
3. 在多个头文件中使用相同的命名空间
比如在头文件 head1 中创建命名空间 qcx,然后在头文件 head2 中创建命名空间 qcx,那么这两个命名空间会合并为一个命名空间。如果在这两个头文件的 qcx 命名空间中定义了相同的名称,编译器会报错。
四、函数缺省值
函数缺省值的作用是不给函数传递参数时,函数使用默认值。在创建顺序表时,通常我们需要传递一个参数来初始化顺序表的大小,但是有时又不确定这个值给多大,给大了浪费空间,给小了需要扩容。所以可以给一个缺省值。
1. 缺省值的使用
// 头文件
#include <iostream>
#include <stdlib.h>// 使用声明
using std::cout;
using std::endl;// 类型声明
typedef int DataType;// 顺序表
struct SQList
{DataType* pdata;size_t size;size_t capacity;
};// 初始化顺序
void InitSQList(SQList* sl, int capacity = 2)
{// 申请空间sl->pdata = (DataType*)malloc(sizeof(DataType) * capacity);if (nullptr == sl->pdata){perror("InitSQList::malloc: ");return;}// 初始化成员sl->size = 0;sl->capacity = capacity;
}// 获得顺序表的容量
size_t GetCapacity(SQList* sl)
{return sl->capacity;
}int main()
{// 创建顺序表SQList s1, s2;// 使用缺省参数InitSQList(&s1);// 传递参数InitSQList(&s2, 8);// 打印容量cout << "s1 的容量:" << GetCapacity(&s1) << endl;cout << "s2 的容量:" << GetCapacity(&s2) << endl;return 0;
}
可以看到程序的运行结果如下:
2. 缺省值使用的注意事项
(1)函数声明填写缺省值,函数定义不写
这样做的好处是防止两边对不上,其次编译阶段需要检查函数声明,如果函数声明不写,函数定义写的话,编译阶段就会报错。
(2)函数缺省值需要从右往左依次填写
由于函数传参是从左到右依次传递的,所以函数缺省值需要从右往左依次缺省。因为C++在传递参数的时候不允许有参数为空。
(3)所有参数都有缺省值叫全缺省,部分参数有缺省值叫班缺省
五、函数重载
函数重载顾名思义就是在相同的作用域中可以存在两个相同名称的函数。这放在 C 中是不允许的,因为 C 中识别函数主要是通过函数名来识别的,而C++中加上了参数。
举个简单的例子,就拿函数 void Swap(int a, int b) 来说,在 C 语言中可能就是通过 Swap 来识别,但是在 C++ 中,是通过 Swapii,来识别,后面的 ii 代表了两个 int 参数。
所以,C++ 支持函数重载,只要函数的参数数量、类型和顺序不同即可。(上述只是简单说明,编译器具体的识别肯定不想上述这么简单)
1. 函数重载的使用
// 头文件
#include <iostream>// 使用声明
using std::cout;
using std::endl;// 交换函数
void Swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}void Swap(double* a, double* b)
{double tmp = *a;*a = *b;*b = tmp;
}int main()
{int a = 1, b = 2;Swap(&a, &b);cout << "a = " << a << endl;cout << "b = " << b << endl;double c = 1.1, d = 2.2;Swap(&c, &d);cout << "c = " << c << endl;cout << "d = " << d << endl;return 0;
}
程序运行结果如下:
&esmp; 可以看到通过使用函数重载,可以把一个函数的功能作用到不同类型的变量上。
2. 为什么函数返回类型不同不算函数重载?
如果两个函数仅仅只是函数返回值不同,那么在编译截断就会报错,由于函数调用语句一模一样,编译器不知道你想调用哪个函数。
六、引用
引用的作用是给已经存在的变量取一个别名,也就是引用变量和被引用的变量共用一块空间。
创建引用变量的格式为:类型 &引用变量名 = 被引用的变量名
1. 引用的使用
// 头文件
#include <iostream>// 使用声明
using std::cout;
using std::endl;int main()
{// 创建变量 aint a = 10;// b 是对 a 的引用,也就是 b 是 a 的别名int& b = a;// 值验证cout << "a = " << a << endl;cout << "b = " << b << endl;// 地址验证cout << "&a = " << &a << endl;cout << "&b = " << &b << endl;return 0;
}
程序的运行结果如下:
可以看到上述变量 a 和 变量 b 的值和地址均相同,可以得出它们都是代指同一块空间。就好像一个人拥有外号,如李逵又叫黑旋风,但是叫的都是同一个人。而引用所代表的就是这种关系。如下图所示:
2. 常量引用
常量引用相比于普通引用的区别就是其值不能修改,类似 const 变量和普通变量。
// 头文件
#include <iostream>// 使用声明
using std::cout;
using std::endl;int main()
{int a = 10;// 普通引用int& ra = a;ra = 1;cout << "a = " << a << endl;return 0;
}
普通引用可以修改:
常量引用不能修改:
从上述代码以及运行结果中可以看出,常量引用不能修改只能读取,普通引用既能修改又能读取。
3. 常量引用和普通引用的区别
1)常量引用既能引用常量又能引用变量,而普通引用只能引用变量。
2)常量引用不能修改,普通引用可以修改
5. 引用传参
引用传参非常好用,首先引用传参效率高,因为直接使用原对象,其次引用传参节省空间,因为引用和引用对象共用一块空间。
下面是使用引用传参的 Swap() 函数:
// 头文件
#include <iostream>// 使用声明
using std::cout;
using std::endl;// 交换函数
void Swap(int& a, int& b)
{int tmp = a;a = b;b = tmp;
}int main()
{int a = 10;int b = 20;// 交换前cout << "交换前:\n";cout << "a = " << a << endl;cout << "b = " << b << endl;// 交换后Swap(a, b);cout << "交换后:\n";cout << "a = " << a << endl;cout << "b = " << b << endl;return 0;
}
代码运行结果如下:
可以看到引用传参比指针传参还要香,不仅传参直接传递,在函数中也可以直接使用。而指针传参需要取地址,在函数中还需要解引用。
而且引用还可以作为返回值,其他类型作为返回值都需要先拷贝到一个临时对象,然后再返回,而引用作为返回值是直接返回,提升了效率。但是引用作为返回值不能返回局部变量。
6. 引用的注意事项
1)引用必须在初始化时绑定对应类型的对象,且绑定之后不能转换绑定对象;
2)引用不开辟空间,和被引用对象共用一块空间;
3)普通引用只能绑定变量,常量引用没有限制;
4)函数不能返回局部变量的引用;
5)传参时如果不需要修改值,传递常量引用,避免不小心修改;
6)不要把引用和指针混淆。
七、内联函数
函数调用需要建立栈帧,但是如果该函数仅仅只有寥寥几行代码,这样每次调用该函数的开销主要在建立栈帧上了。
C 语言通过宏来解决上述问题,如下代码:
// 头文件
#include <iostream>// 使用声明
using std::cout;
using std::endl;// 宏声明
#define Add(x, y) (((x) + (y)) * 10)int main()
{cout << Add(10, 20) << endl;return 0;
}
通过上述代码可以发现,虽然宏能解决这个问题。但是宏是在编译过程中直接替换的,也不进行类型检查,且写法复杂,又由于运算符优先级要在表达式的每个部分加上括号。
C++ 通过内联函数解决上述问题,直接在函数前面加上 inline 即可。内联函数的作用是,当运行到函数调用语句时,直接展开函数体,也就是用函数体替换函数调用语句。
1. 内联函数的使用
// 头文件
#include <iostream>
#include "head1.h"// 使用声明
using std::cout;
using std::endl; 宏声明
//#define Add(x, y) (((x) + (y)) * 10)int main()
{ 宏声明//cout << Add(10, 20) << endl;// 内联函数Add(10, 20); // 相当于 return (10 + 20) * 10;return 0;
}
内联函数相当于在函数调用语句处展开函数体(带入参数值)。
2. 内联函数的注意事项
1)online 关键字只能添加在函数声明;
2)添加 online 关键字只是建议编译器让该函数成为内联函数,具体还需要编译器自行判断;
3)一般把内联函数直接定义在头文件中,其他文件需要使用只需要包含该头文件即可;
4)长度过长的函数和递归函数不适合成为内联函数,
5)内联函数只在 release 下起作用,在 debug 下不起作用;
6)内联函数不建议声明和定义分离,因为 inline 展开了,就找不到函数地址了,链接错误。
3. 宏的优缺点?C++ 有哪些技术替代宏?
(1)
优点:
1)针对不带参宏,提升了代码的可读性和可维护性;
2)针对带参宏,减少了函数栈帧的开销,提升了效率。
缺点:
1)缺少类型检查;
2)针对带参宏,可读性差,可维护性差,容易用错(由于运算符的优先级,必须在表达式的每个部分加上括号)
(2)
1)C++ 使用关键字 const 来定义常量;
2)C++ 使用内联函数替换带参宏。
八、auto 关键字
auto 关键字的作用是在创建变量的时候根据赋值表达式的类型推断出变量的类型。
当变量的类型复杂时,使用 auto 关键字非常方便且不易出错。
1. auto 关键字的使用
// 头文件
#include <iostream>// 使用声明
using std::cout;
using std::endl;int main()
{auto a = 1; // intauto b = 1.1; // doubleauto c = 'a'; // char auto d = "aaaaa"; // const char*auto e = 1 + 1.1; // doublereturn 0;
}
从上述代码中的最后一条 auto 赋值语句中可以得出,auto 语句是根据表达式的值进行类型推断的。
2. auto 关键字使用的注意事项
1)在早期的 C/C++ 中,auto 关键字修饰的变量是具有自动存储器的局部变量。由于在函数中默认创建的变量就是局部变量,所以导致该关键字几乎没人使用。所以,C++11 标准赋予该关键字根据赋值表达式推断类型的能力。
2)使用 auto 关键字必须对变量初始化,因为 auto 关键字需要根据表达式的类型来推断该变量的类型。因此 auto 并非是一种类型声明,而是一个类型声明时的占位符,编译器在编译器会把 auto 替换为该变量对应的类型。
3)用 auto 声明指针类型时,使用 auto 和 auto* 没有任何区别,只是后者显示表示该类型是个指针。
4)用 auto 声明引用类型时必须使用 auto&。
5)使用 auto 在一行定义多个变量时,这些变量的基本类型必须相同。如:int、int*、int&,它们的基本类型都是 int。
6)auto 不能用来作为函数参数,也不能直接用来声明数组。
九、基于范围的 for 循环
范围 for 是 C++11 新增的一种遍历方法,for 后面的圆括号被冒号(:)分为两部分,前者是范围内用于迭代的变量,后者是被迭代的范围。
迭代的变量被依次赋予迭代范围中的值,所以正常情况下只能读取数据,就相当于把范围中的值依次拷贝到迭代的变量中。所以一般情况下使用引用,这样既减少了拷贝的环节,又可以修改范围中的数据。当只需要读取数据时,前面加上 const 即可。
1. 范围 for 的使用
// 头文件
#include <iostream>// 使用声明
using std::cout;
using std::endl;// 常量声明
const int SIZE = 10;int main()
{int arr[SIZE];for (int i = 1; i <= 10; ++i)arr[i - 1] = i;// 使用范围 for 变量数组for (auto& elem : arr){cout << elem << " ";elem *= 2;}cout << endl;for (auto& elem : arr)cout << elem << " ";return 0;
}
代码的运行结果如下:
与普通的循环一样,可以使用 continue 或者 break 跳出循环。
2. 范围 for 的使用条件
1)迭代的范围必须是确定的,如数组就是第一个元素到最后一个元素;
2)迭代的对象要实现++和==的操作。(范围 for 的本质是迭代器)
十、空指针 nullptr(C++11)
在 C 语言中,空指针使用 NULL 表示。但是在 C++ 中,NULL 是一个宏,即 #define NULL 0。所以它的本质是数字 0,而在 C++ 中,关键字 nullptr 代表空指针。如下代码:
// 头文件
#include <iostream>// 使用声明
using std::cout;
using std::endl;// 函数定义
void func(int)
{cout << "func1(int)" << endl;
}void func(int*)
{cout << "func2(int*)" << endl;
}int main()
{func(0);func(NULL);func(nullptr);
}
代码运行结果如下:
可以看到当函数重载既有 int 参数又有指针参数时,NULL 会优先使用 int 参数的函数。所以在 C++ 中,尽量使用 nullptr 作为空指针。
&esmp;首先,nullptr 是 C++ 的关键字,使用时不需要包含头文件。且在 C++11 中,sizeof(nullptr) 和 sizeof((void*)0) 的结果相同。
相关文章:

《深入探究:C++ 在多方面对 C 语言实现的优化》
目录 一、C 在 C 上进行的优化二、C 关键字(C 98)三、C 的输入输出1. cin 和 cout 的使用2. cin、cout 和 scanf()、printf() 的区别 三、命名空间1. 命名空间的使用2. 嵌套命名空间3. 在多个头文件中使用相同的命名空间 四、函数缺省值1. 缺省值的使用2…...

React 第十六节 useCallback 使用详解注意事项
useCallback 概述 1、useCallback 是在React 中多次渲染缓存函数的 Hook,返回一个函数的 memoized的值; 2、如果多次传入的依赖项不变,那么多次定义的时候,返回的值是相同的,防止频繁触发更新; 3、多应用在 父组件为函…...

使用C#和OPenCV实现圆形检测
文章目录 霍夫变换使用 OpenCV 和 C# 实现圆形检测 霍夫变换 在计算机视觉中,圆形检测是一个常见且有用的任务,特别是在物体识别、图像分析和图形处理等领域。OpenCV 是一个强大的开源计算机视觉库,它提供了许多工具来实现不同的图像处理功能…...
评估一套呼叫中心大模型呼入机器人的投入回报比?
评估一套呼叫中心大模型呼入机器人的投入回报比? 原作者:开源呼叫中心FreeIPCC,其Github:https://github.com/lihaiya/freeipcc 评估一套呼叫中心大模型呼入机器人的投入回报比(ROI),是一个多…...

十八、Label 和 Selector
Label 是键值对,用来标识 Kubernetes 资源(如 Pod、Node、Service 等)的属性。它们并不直接影响资源的行为,但可以帮助用户快速组织、查询和操作这些资源。标签可以用于选择、过滤和分组。 Label: 标签对 k8s 中各种资源进行分类、分组,如Pod和节点进行分组。通过添加kev…...

实现按键按下(低电平)检测到下降沿
按照流程进行编程 步骤1: 初始化函数 包括时基工作参数配置 输入通道配置 更新中断使能 使能捕获、捕获中断及计数器 HAL_TIM_IC_Init(&ic_handle) //时基参数配置 HAL_TIM_IC_ConfigChannel(&ic_handle,&ic_config,TIM_CHANNEL_2) //输…...
解析 SSM 垃圾分类系统,助力生态平衡
前 言 垃圾分类系统,传统的垃圾分类系统模式还处于线下管理阶段,管理效率极低。随着垃圾分类系统信息的不断增多,传统基于线下管理模式已经无法满足当前用户需求,随着信息化时代的到来。通过该系统的设计,管理员可以管…...

软件工程 设计的复杂性
复杂性代表事件或事物的状态,它们具有多个相互关联的链接和高度复杂的结构。在软件编程中,随着软件设计的实现,元素的数量以及它们之间的相互联系逐渐变得庞大,一下子变得难以理解。 如果不使用复杂性指标和度量,软件…...
Nginx 限制只能白名单 uri 请求的配置
实际生产项目中,大多数时候我们会将后端的 http 接口通过前置 nginx 进行反向代理,对互联网用户提供服务。往往我们后端服务所能提供的接口服务是大于互联网用户侧的实际请求的接口地址数量的(例如后端服务一共有100个api接口,经过…...
QT c++ 同时使用sqlite 和mysql数据库的问题
在项目开发中,同时使用了sqlite 和mysql数据库,分开这两部分运行功能都正常,但是一起运行,就异常,sqlite部分不能使用。 现象:出现如下提示 QSqlDatabasePrivate::addDatabase: duplicate connection nam…...

redis集群 服务器更换ip,怎么办,怎么更换redis集群的ip
redis集群 服务器更换ip,怎么办,怎么更换redis集群的ip 1、安装redis三主三从集群2、正常状态的redis集群3、更改redis集群服务器的ip 重启服务器 集群会down4、更改redis集群服务器的ip 重启服务器 集群down的原因5、更改redis集群服务器的ip后…...

【C++习题】19.数组中第K个大的元素
题目:数组中第K个大的元素 链接🔗:数组中第K个大的元素 题目: 代码: class Solution { public:int findKthLargest(vector<int>& nums, int k) {// 将数组中的元素先放入优先级队列中priority_queue<i…...

JIS-CTF: VulnUpload靶场渗透
JIS-CTF: VulnUpload来自 <https://www.vulnhub.com/entry/jis-ctf-vulnupload,228/> 1,将两台虚拟机网络连接都改为NAT模式 2,攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 靶机IP地址192.168.23.162,攻击机IP地址192.168.23.140…...
BGP-面试
简单介绍一下BGP BGP,边界网关协议,属于路径矢量路由协议。属于触发式更新或者增量更新。具有丰富的路由策略,能够灵活的进行路由选择。重心不是在路由学习,而是路由优选、更高效的传递路由和维护大量的路由信息。基于TCP…...

Git-安装与常用命令
目录 1.Git环境配置 1.1下载 1.2配置 1.2.1基本配置 1.2.2常用指令配置别名 1.2.3获取本地仓库 git命令在git bash中演示,会用到一些Linux命令。 1.Git环境配置 1.1下载 Git下载地址:https://git-scm.com/download 傻瓜式安装就可以了。 安装…...

回归预测 | Matlab实现基于BiLSTM-Adaboost双向长短期记忆神经网络结合Adaboost集成学习回归预测
目录 效果一览基本介绍模型设计程序设计参考资料效果一览 基本介绍 回归预测 | Matlab实现基于BiLSTM-Adaboost双向长短期记忆神经网络结合Adaboost集成学习回归预测 模型设计 基于BiLSTM-Adaboost的回归预测模型结合了双向长短期记忆神经网络(BiLSTM)和Adaboost集成学习的…...

微信小程序跳转其他小程序以及跳转网站
一、跳转其他小程序 1.1 知道appid和页面路径 wx.navigateToMiniProgram({appId: appid, // 替换为目标小程序 AppIDpath: pathWithParams, // 小程序路径envVersion: release, // 开发版、体验版或正式版success(res) {console.log("跳转到其他小程序成功!&q…...
Not using native diff for overlay2, this may cause degraded performance……
问题现象 案例:Anolis 8.9(4.19.91-26.an8.x86_64) Overlay2存储驱动程序) 当我们安装好Docker之后,通过systemctl status docker -l 会发现有一个告警信息:levelwarning msg"Not using native dif…...

【自用】管材流转项目 数据库恢复之 PIPE 表 二维码相关 各个表恢复 SQL
总览 1.后端前端和数据库 PIPE 页面的关系 2.后端批量生成二维码 jpg 图片 3.为了保证 PIPE 正常使用的调整 4.TRANSFORM(流转表) 一、后端前端和数据库 PIPE 页面的关系 1.前端 关于PIPE页面,首先,在前端,我们已经…...

【渗透测试】信息收集二
其他信息收集 在渗透测试中,历史漏洞信息收集是一项重要的工作,以下是相关介绍: 历史漏洞信息收集的重要性 提高效率:通过收集目标系统或应用程序的历史漏洞信息,可以快速定位可能存在的安全问题,避免重复…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
智能职业发展系统:AI驱动的职业规划平台技术解析
智能职业发展系统:AI驱动的职业规划平台技术解析 引言:数字时代的职业革命 在当今瞬息万变的就业市场中,传统的职业规划方法已无法满足个人和企业的需求。据统计,全球每年有超过2亿人面临职业转型困境,而企业也因此遭…...
鸿蒙HarmonyOS 5军旗小游戏实现指南
1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发,采用DevEco Studio实现,包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...