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

C++_C++11的学习

1. 统一的列表初始化

1.1{}初始化

        在C++98 中,标准就已经允许使用花括号 {} 数组或者结构体元素进行统一的列表初始值设定。而到了C++11,标准扩大了用大括号括起的列表 ( 初始化列表 )的使用范围,使其能适用于所有的内置类型和自定义类型,而且使用初始化列表时可用可不用=
struct Point
{int _x;int _y;
};
class Date
{
public:Date(int year, int month, int day):_year(year), _month(month), _day(day){cout << "Date(int year, int month, int day)" << endl;}
private:int _year;int _month;int _day;
};
int main()
{int x1 = 1;int x2{ 2 };int array1[]{ 1, 2, 3, 4, 5 };int array2[5]{ 0 };Point p{ 1, 2 };// C++11中列表初始化也可以适用于new表达式中int* pa = new int[4] { 0 };//C++98Date d1(2022, 1, 1);//C++11Date d2{ 2022, 1, 2 };Date d3 = { 2022, 1, 3 };return 0;
}

1.2 std::initializer_list

std::initializer_list 一般是作为构造函数的参数, C++11 STL 中的不少容器就增加。
std::initializer_list 作为参数的构造函数,这样初始化容器对象就更方便了。也可以作为 operator=
的参数,这样就可以用大括号赋值。

int main()
{vector<int> v = { 1,2,3,4 };list<int> lt = { 1,2 };// 这里{"sort", "排序"}会先初始化构造一个pair对象map<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };// 使用大括号对容器赋值v = { 10, 20, 30 };return 0;
}

以vector为例,讲一下initializer_list的使用:
        在C++11中,vector新增了如下的构造函数

	//先构造再拷贝 -> 编译器优化 -> 直接构造vector<int> v1 = { 1,2,3,4,5,6,7,8,9 };//直接构造vector<int> v2{ 1,2,3,4,5,6,7,8,9 };

2. 声明

2.1 auto

        在C++98 中auto是一个存储类型的说明符,表明变量是局部自动存储类型。 但是局部域中定义局 部的变量默认就是自动存储类型,所以 auto 就没什么价值了。 C++11中废弃 auto 原来的用法,将 其用于实现自动类型腿断。这样要求必须进行显示初始化,让编译器将定义对象的类型设置为初始化值的类型。 因此 auto 并非是一种 类型 的声明,而是一个类型声明时的 占位符 ,编译器在编
译期会将 auto 替换为变量实际的类型。

2.1.1 auto的使用细则

1. auto与指针和引用结合起来使用
        用auto声明指针类型时,用
autoauto*没有任何区别,但用auto声明引用类型时则必须&

2. 在同一行定义多个变量
        当在同一行声明多个变量时,这些变量必须是相同的类型,否则,编译器将会报错,因为编译 器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量

2.1.2 auto不能推导的场景

1. auto 不能作为函数的参数
        因为编译器无法对函数参数的实际类型进行推导
2. auto 不能直接用来声明数组

 

2.2 decltype

关键字decltype将变量的类型声明为表达式指定的类型

template<class T1, class T2>
void F(T1 t1, T2 t2)
{decltype(t1 * t2) ret;cout << typeid(ret).name() << endl;
}
int main()
{const int x = 1;double y = 2.2;decltype(x * y) ret; // ret的类型是doubledecltype(&x) p;      // p的类型是int*cout << typeid(ret).name() << endl;cout << typeid(p).name() << endl;F(1, 'a');return 0;
}

2.3 nullptr

        由于C++ NULL 被定义成字面量 0 ,这样就可能回带来一些问题,因为 0 既能指针常量,又能表示整形常量。所以出于清晰和安全的角度考虑,C++11 中新增了 nullptr ,用于表示空指针。
注意:
        1. 在使用 nullptr 表示指针空值时不需要包含头文件,因为 nullptr C++11 作为新关键字
        2. 在 C++11 中, sizeof(nullptr) sizeof((void*)0) 所占的字节数相同。

3. 基于范围的for循环

3.1 范围for的语法

        对于一个有范围的集合 而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因此C++11 中引入了基于范围的 for 循环。 for 循环后的括号由冒号 分为两部分:第一部分是范 围内用于迭代的变量,第二部分则表示被迭代的范围
int main() {int array[] = { 1, 2, 3, 4, 5 };// 如果要进行修改,就必须要引用for (auto& e : array)e *= 2;// 如果只是访问,可以不用引用for (auto e : array)cout << e << " " << endl;return 0;
}
注意:与普通循环类似,可以用 continue 来结束本次循环,也可以用 break 来跳出整个循环。

3.2 范围for的使用条件

1. for 循环迭代的范围必须是确定的
        对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供begin和 end 的方法, begin end 就是 for 循环迭代的范围。
2. 迭代的对象要实现 ++ == 的操作
        因为对于编译器,编译器范围for的使用最后还是要转化为一般for循环的遍历
int main() {vector<int> v = { 1, 2, 3, 4, 5 };vector<int>::iterator it = v.begin();for (auto e : v)cout << e << " ";cout << endl;for (; it != v.end(); it++)cout << *it << " ";return 0;
}

4. STL中一些变化

4.1 新容器

        在原有容器的基础上新加了如下所标记的容器

 4.2 新方法

1.提供了cbegincend方法返回const迭代器等等
        但是实际意义不大,因为begin和end
也是可以返回const迭代器的。
2.
提供了各容器的initializer_list构造
3.push系列、insert、emplace等函数增加了右值引用的插入版本
4.容器增加了移动构造和移动赋值

总结:C++11引入了右值引用和移动语义,解决了左值引用的一些问题并极大提高了效率

5. 新的类功能

5.1 默认成员函数

原来C++ 类中,有 6 个默认成员函数:
        1. 构造函数
        2. 析构函数
        3. 拷贝构造函数
        4. 拷贝赋值重载
        5. 取地址重载
        6. const 取地址重载
        最后重要的是前4个,后两个用处不大。默认成员函数就是我们不写编译器会生成一个默认的。C++11 新增了两个:移动构造函数移动赋值运算符重载
针对移动构造函数和移动赋值运算符重载有一些需要注意的点如下:
        1.如果你没有自己实现移动构造函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个。那么编译器会自动生成一个默认移动构造。默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝;自定义类型成员,则需要看这个成员是否实现移动构造,如果实现了就调用移动构造,没有实现就调用拷贝构造。
        2.如果你没有自己实现移动赋值重载函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个,那么编译器会自动生成一个默认移动赋值。默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝;自定义类型成员,则需要看这个成员是否实现移动赋值,如果实现了就调用移动赋值,没有实现就调用拷贝赋值。
        3.如果你提供了移动构造或者移动赋值,编译器不会自动提供拷贝构造和拷贝赋值

5.2 类成员变量初始化

       C++11允许在类定义时给成员变量初始缺省值,默认生成构造函数会使用这些缺省值初始化。

5.3 强制生成默认函数的关键字default

        C++11可以让你更好的控制要使用的默认函数。假设你要使用某个默认的函数,但是因为一些原因这个函数没有默认生成。比如:我们提供了拷贝构造,就不会生成移动构造了,那么我们可以使用default 关键字显示指定移动构造生成。

5.4 禁止生成默认函数的关键字delete

        如果能想要限制某些默认函数的生成,在C++98 中,是该函数设置成 private ,并且只声明补丁而已,这样只要其他人想要调用就会报错。在C++11 中更简单,只需在该函数声明加上 =delete 即可,该语法指示编译器不生成对应函数的默认版本,称=delete 修饰的函数为删除函数。

5.5 继承和多态中的finaloverride关键字

1.final: 修饰时,它表示该类不能被继承
             修饰虚函数时,它表示该虚函数不能在子类中被重写
2.override: 检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错

6. 可变参数模板

        C++11的新特性可变参数模板能够让您创建可以接受可变参数函数模板和类模板,相比 C++98/03,类模版和函数模版中只能含固定数量的模版参数,可变模版参数是一个巨大的改进。
// Args是一个模板参数包,args是一个函数形参参数包
// 声明一个参数包Args...args,这个参数包中可以包含0到任意个模板参数。
template <class ...Args>
void ShowList(Args... args)
{}
        我们把带省略号的参数称为“ 参数包” ,它里面包含了 0 N N>=0 )个模版参数。我们无法直接获取参数包 args 中的每个参数的,只能通过展开参数包的方式来获取参数包中的每个参数,下面是主要的两种方式:

1. 递归函数方式展开参数包

// 每次递归都会获取并显示1个参数直至全部参数获取完就结束
template <class T>
void ShowList(const T& t)
{cout << t << endl;
}
// 展开函数
template <class T, class ...Args>
void ShowList(T value, Args... args)
{cout << value << " ";ShowList(args...);
}
int main()
{ShowList(1);ShowList(1, 'A');ShowList(1, 'A', std::string("sort"));return 0;
}

2. 逗号表达式展开参数包

        PrintArg不是一个递归终止函数,只是一个处理参数包中每一个参数的函数。这种就地展开参数包的方式实现的关键是逗号表达式:
        函数中的逗号表达式:(printarg(args), 0),也是按照这个执行顺序,先执行printarg(args),再得到逗号表达式的结果0。同时还用到了
C++11的另外一个特性——初始化列表,通过初始化列表来初始化一个变长数组, {(printarg(args), 0)...}将会展开成((printarg(arg1),0), (printarg(arg2),0), (printarg(arg3),0), etc... ),最终会创建一个元素值都为0的数组int arr[sizeof...(Args)]。同时,逗号表达式的前面部分会执行PrintArg函数打印参数,这个数组的目的纯粹是为了在数组构造的过程展开参数包

template <class T>
void PrintArg(T t)
{cout << t << " ";
}
//展开函数
template <class ...Args>
void ShowList(Args... args)
{int arr[] = { (PrintArg(args), 0)... };cout << endl;
}
int main()
{ShowList(1);ShowList(1, 'A');ShowList(1, 'A', std::string("sort"));return 0;
}

3. STL容器中的empalce相关接口函数

std::vector::emplace_back
template <class... Args>  void emplace_back (Args&&... args);std::list::emplace_back
template <class... Args>  void emplace_back (Args&&... args);

        STL中的容器大多都实现了可参数列表式的empalce式的接口函数,它和insert、push式的函数比较如下:
1. 插入类型是单个值,两个没什么区别
2. 直接给插入对象参数时,empalce系列对于深拷贝的类对象,减少一次移动构造,对于浅拷贝的类对象,减少一次拷贝构造

7. lambda表达式

7.1 书写格式

lambda 表达式书写格式: [capture-list] (parameters) mutable -> return-type { statement }
lambda 表达式各部分说明:
1.[capture-list] : 捕捉列表 ,该列表总是出现在 lambda 函数的开始位置, 编译器根据 [] 判断接下来的代码是否为 lambda 函数 捕捉列表能够捕捉上下文中的变量供 lambda 函数使用 (必写)
2.(parameters) :参数列表。与 普通函数的参数列表一致 ,如果不需要参数传递,则可以连同() 一起省略。
3.mutable :默认情况下, lambda 函数总是一个 const 函数, mutable 可以取消其常量性。使用该修饰符时,参数列表不可省略( 即使参数为空 )
4.returntype:返回值类型。用 追踪返回类型形式声明函数的返回值类型 ,没有返回值时此部分可省略。返回值类型明确情况下,也可省略,由编译器对返回类型进行推
5.{statement}:函数体。在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量. (必写)
注意:
        在lambda 函数定义中, 参数列表和返回值类型都是可选部分,而捕捉列表和函数体可以 。因此 C++11 最简单的 lambda 函数为: []{} ; lambda函数不能做任何事情。 表达式实际上可以理解为无名函数,在语法层没有类型,该函数无法直接调 用,如果想要直接调用,可借助 auto 将其赋值给一个变量,或者用decltype推导表达式的类型,lambda对象禁止了默认构造。
void Test()
{auto f = [] {cout << "hello world" << endl; };f();
}class Date
{
public:Date(int year = 1, int month = 1, int day = 1):_year(year), _month(month), _day(day){cout << "Date(int year, int month, int day)" << endl;}Date(const Date& d):_year(d._year), _month(d._month), _day(d._day){cout << "Date(const Date& d)" << endl;}
private:int _year = 1;int _month = 1;int _day = 1;
};int main()
{auto DateLess = [](const Date* p1, const Date* p2){return p1 < p2;//偷懒直接比指针};cout << typeid(DateLess).name() << endl;// lambda对象支持拷贝构造auto copy(DateLess);// lambda对象禁掉默认构造// decltype(DateLess) xx;//运行报错//为了下面的代码运行通过,还得有比较对象DateLess,因为lambda对象不会默认构造priority_queue<Date*, vector<Date*>, decltype(DateLess)> p1(DateLess);return 0;
}

7.2 函数对象与lambda表达式

        函数对象,又称为仿函数,即可以想函数一样使用的对象,就是在类中重载了operator() 运算符的类对象。
class Rate
{
public:Rate(double rate) : _rate(rate){}double operator()(double money, int year){return money * _rate * year;}
private:double _rate;
};int main()
{double rate = 0.49;Rate r1(rate);r1(10000, 2);auto r2 = [=](double monty, int year)->double {return monty * rate * year;};r2(10000, 2);auto f1 = [] {cout << "hello world" << endl; };auto f2 = [] {cout << "hello world" << endl; };f1();f2();return 0;
}

通过查看汇编代码可以知道,编译器对于lambda表达式的处理最终还是转换成对仿函数的处理,而且还可以知道,编译器对这个转换后的仿函数的地址对于相同的lambda表达式是不同的,这就解释了为什么lambda表达式间是不支持赋值的,即使看上去类型相同。

8. 包装器

8.1 function包装器

//std::function在头文件<functional>
// 类模板原型如下
template <class T> function;     // undefined
template <class Ret, class... Args>
class function<Ret(Args...)>;模板参数说明:
Ret : 被调用函数的返回类型
Args…:被调用函数的形参

        function包装器也叫作适配器。C++中的function本质是一个类模板,也是一个包装器,是对可调用对象的再封装,统一类型,可调用对象有函数指针/函数名、仿函数、lambda表达式等。   
        
 对于编译器而言,下面的代码模useF板会实例化3份:

template<class F, class T>
T useF(F f, T x)
{static int count = 0;cout << "count:" << ++count << endl;cout << "count:" << &count << endl;return f(x);
}double f(double i)
{return i / 2;
}struct Functor
{double operator()(double d){return d / 3;}
};int main()
{// 函数名cout << useF(f, 11.11) << endl;// 函数对象cout << useF(Functor(), 11.11) << endl;// lamber表达式cout << useF([](double d)->double { return d / 4; }, 11.11) << endl;return 0;
}

 

         而如果使用function进行封装后得到的可调用类型是一样的,实例化就只有1份,function的使用无疑减小了模板实例化的开销:

int main()
{// 函数指针function<double(double)> fc1 = f;fc1(11.11);cout << useF(fc1, 11.11) << endl;// 函数对象function<double(double)> fc2 = Functor();fc2(11.11);cout << useF(fc2, 11.11) << endl;// lambda表达式function<double(double)> fc3 = [](double d)->double { return d / 4; };fc3(11.11);cout << useF(fc3, 11.11) << endl;return 0;
}

        除了上述的可调用对象,function还能对类的(静态)成员函数进行封装:

int f(int a, int b)
{return a + b;
}class Plus
{
public:static int plusi(int a, int b){return a + b;}double plusd(double a, double b){return a + b;}
};int main()
{// 普通函数function<int(int, int)> fc1 = f;cout << fc1(1, 1) << endl;// 静态成员函数function<int(int, int)> fc2 = &Plus::plusi;cout << fc2(1, 1) << endl;// 非静态成员函数// 非静态成员函数需要对象的指针或者对象去进行调用// 因为非静态成员函数还有一个隐式参数:this/*Plus plus;function<double(Plus*, double, double)> fc3 = &Plus::plusd;cout << fc3(&plus, 1, 1) << endl;*/function<double(Plus, double, double)> fc3 = &Plus::plusd;cout << fc3(Plus(), 1, 1) << endl;return 0;
}

8.2 bind

template <class Fn, class... Args>/* unspecified */ bind (Fn&& fn, Args&&... args);template <class Ret, class Fn, class... Args>/* unspecified */ bind (Fn&& fn, Args&&... args);
        std::bind函数定义在头文件中, 是一个函数模板,它就像一个函数包装器 ( 适配器 ) 接受一个可 调用对象 ,生成一个新的可调用对象来 适应 原对象的参数列表
        调用bind 的一般形式: auto newCallable = bind(callable,arg_list); 其中,newCallable 本身是一个可调用对象, arg_list 是一个逗号分隔的参数列表,对应给定的callable的参数。 当我们调用 newCallable 时, newCallable 会调用 callable, 并传给它 arg_list 的参数
        arg_list中的参数可能包含形如 _n 的名字,其中 n 是一个整数,这些参数是 占位符 ,表示
newCallable 的参数,它们占据了传递给 newCallable 的参数的 位置 。数值 n 表示生成的可调用对象中参数的位置:_1 newCallable 的第一个参数, _2 为第二个参数,以此类推。 它的功能如下:

1. 调整参数顺序(意义不大)

int Sub(int a, int b)
{return a - b;
}class Plus
{
public:static int plusi(int a, int b){return a + b;}double plusd(double a, double b){return a - b;}
};int main()
{// 调整参数顺序,意义不大int x = 10, y = 20;cout << Sub(x, y) << endl;auto f1 = bind(Sub, placeholders::_2, placeholders::_1);cout << f1(x, y) << endl;function<double(Plus, double, double)> fc3 = &Plus::plusd;cout << fc3(Plus(), 1, 1) << endl;return 0;
}

2. 调整参数个数(意义大)

int main()
{// 调整参数的个数// 某些参数绑死function<double(double, double)> fc4 = bind(&Plus::plusd, Plus(), placeholders::_1, placeholders::_2);cout << fc4(2, 3) << endl;function<double(double)> fc5 = bind(&Plus::plusd, Plus(), placeholders::_1, 20);cout << fc5(2) << endl;return 0;
}

相关文章:

C++_C++11的学习

1. 统一的列表初始化 1.1&#xff5b;&#xff5d;初始化 在C98 中&#xff0c;标准就已经允许使用花括号 {} 对数组或者结构体元素进行统一的列表初始值设定。而到了C11&#xff0c;标准扩大了用大括号括起的列表 ( 初始化列表 )的使用范围&#xff0c;使其能适用于所有的内…...

RAC11G参数修改错误导致启库失败处理

问题描述 部署完一套3节点的11g RAC后&#xff0c;进行了内存的参数优化&#xff0c;优化时忘记了先备份参数文件&#xff0c;忘记了计算内存参数眼盲的复制粘贴执行内存优化sql导致优化后重启实例启动失败。艾&#xff0c;由于粗心自己给自己挖了个坑。 切记更改参数步骤&am…...

UE4打包Win64项目命令行

仅用于个人记录&#xff0c;写的粗糙&#xff0c;勿喷 BuildProject.bat 具体命名参数请参照UE引擎RunUAT源码&#xff08;Programs\AutomationTool下Program.cs&#xff09; 参数1&#xff1a;引擎安装路径 参数2&#xff1a;uproject路径 参数3&#xff1a;输出路径 参数…...

c语言bug汇总中篇5

40. 不关注代码风格一致性 代码风格一致性有助于提高代码的可读性和可维护性。如果团队成员使用不同的代码风格&#xff0c;会导致代码看起来杂乱无章&#xff0c;增加阅读和理解的成本。 为了保持代码风格的一致性&#xff0c;程序员应该&#xff1a; - 遵循团队或项目约定的…...

【linux】进程(一)

1. 冯诺依曼体系结构 计算机基本都遵循着冯诺依曼体系 我们使用的计算器是由一个个硬件构成的&#xff1a; 中央控制器&#xff08;CPU&#xff09; &#xff1a; 运算器 控制器 等输入设备 : 键盘&#xff0c;鼠标&#xff0c;网卡 等输出设备 : 显示器&#xff0c;网卡 等…...

手把手教你用Python轻松玩转SQL注入

一、浅谈SQL注入 SQL注入其实就是把SQL命令插入到WEB表单中提交或者输入一些页面请求的查询字符串&#xff0c;比如我们输网址&#xff0c;就是相当于这种操作&#xff0c;只不过我们不是在测试SQL注入漏洞&#xff0c;而仅仅只是为了输入后看到相应网页上的内容而已。一般方法…...

redis的几种部署模式及注意事项

Redis 可以以多种部署模式来满足不同的需求&#xff0c;其中一些常见的部署模式包括&#xff1a;单节点部署、主从复制部署、哨兵模式部署和集群部署。这些部署模式各有特点&#xff0c;适用于不同的场景和需求&#xff1a; 概念 单节点部署&#xff1a; 特点&#xff1a;单…...

使用Python生成一束玫瑰花

520到了&#xff0c;没时间买花&#xff1f;我们来生成一个电子的。 Python不仅是一种强大的编程语言&#xff0c;用于开发应用程序和分析数据&#xff0c;它也可以用来创造美丽的艺术作品。在这篇博客中&#xff0c;我们将探索如何使用Python生成一束玫瑰花的图像。 准备工作…...

紫光同创PGL22G开发板|盘古22K开发板,国产FPGA开发板,接口丰富

盘古22K开发板是基于紫光同创Logos系列PGL22G芯片设计的一款FPGA开发板&#xff0c;全面实现国产化方案&#xff0c;板载资源丰富&#xff0c;高容量、高带宽&#xff0c;外围接口丰富&#xff0c;不仅适用于高校教学&#xff0c;还可以用于实验项目、项目开发&#xff0c;一板…...

大模型的实践应用24-LLaMA-Factory微调通义千问qwen1.5-1.8B模型的实例

大家好,我是微学AI,今天给大家介绍一下大模型的实践应用24-LLaMA-Factory微调通义千问qwen1.5-1.8B模型的实例, LLaMA-Factory是一个专门用于大语言模型微调的框架,它支持多种微调方法,如LoRA、QLoRA等,并提供了丰富的数据集和预训练模型,便于用户进行模型微调。通义千问…...

力扣爆刷第142天之二叉树五连刷(构造树、搜索树)

力扣爆刷第142天之二叉树五连刷&#xff08;构造树、搜索树&#xff09; 文章目录 力扣爆刷第142天之二叉树五连刷&#xff08;构造树、搜索树&#xff09;一、106. 从中序与后序遍历序列构造二叉树二、654. 最大二叉树三、617. 合并二叉树四、700. 二叉搜索树中的搜索五、98. …...

0407放大电路的频率响应

放大电路的频率响应 单时间常数RC电路的频率响应中频响应高频响应低频响应全频域响应 放大电路频率响应概述1. 直接耦合放大电路频域响应阻容耦合放大电路频域响应 4.7.1 单时间常数RC电路的频率响应 4.7.2 放大电路频率响应概述 4.7.3 单级共射极放大电路的频率响应 4.7.4 单级…...

数据分析必备:一步步教你如何用Pandas做数据分析(6)

1、Pandas 函数应用 Pandas 重建索引操作实例 要将您自己或其他库的函数应用于Pandas对象&#xff0c;您应该了解三个重要的方法。方法如下所述。要使用的适当方法取决于您的函数是希望对整个数据帧进行操作&#xff0c;还是行操作还是按列操作&#xff0c;还是按元素操作。 表…...

Spring Cloud系列—Spring Cloud Gateway服务网关的部署与使用指南

Gateway网关 文章目录 Gateway网关1. 网关基本简介1.1 什么是网关1.2 为什么需要网关&#xff1f; 2. 快速搭建gateway网关2.1 创建新模块2.2 引入依赖2.3 编写启动类2.4 配置路由规则2.5 测试 3. 路由过滤4. 过滤器4.1 简介4.2 网关过滤器4.2.2 种类 4.3 自定义过滤器4.3.1 自…...

创建一个python的Django项目文件

创建一个python的Django项目文件(内含conda) 文章目录 创建一个python的Django项目文件(内含conda)前言一、conda环境的下载二、配置conda的环境变量三、激活管理环境四、下载Django五、创建Django项目文件六、启动Django文件七、用pycharm直接创建Django文件 前言 大家好,今天…...

NB49 牛群的秘密通信

描述 在一个远离人类的世界中&#xff0c;有一群牛正在进行秘密通信。它们使用一种特殊的括号组合作为加密通信的形式。每一组加密信息均包括以下字符&#xff1a;(,{,[,),},]。 加密信息需要满足以下有效性规则&#xff1a; 每个左括号必须使用相同类型的右括号闭合。左括号…...

Git系列:git mv 高效的文件重命名与移动操作

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…...

美区TikTok小店又出潜力爆品!“痘痘贴”一周销售八万单!

保健品在美区小店“大杀四方”的同时&#xff0c;个别美妆个护单品也在悄悄上分。 据超店有数的「销量飙升榜」显示&#xff0c;一款由Zikoo推出的“痘痘贴”最近一周内销量正在飞速上升&#xff0c;环比增长高达209.29%&#xff0c;销量近8万件。 来源&#xff1a;超店有数「销…...

C++两种内置栈的使用

第一种&#xff1a;使用C内置栈数据类型 stack<int> q; //C内置栈数据类型 int x; q.push(x); //将x压入栈顶 q.top(); //返回栈顶的元素 q.pop(); //删除栈顶的元素 q.size(); //返回栈中元素的个数 q.empty(); //检查栈是否为空,若为空返回true,否则返回false第二…...

如何用电脑批量操作多部手机

如果你有很多手机&#xff0c;然后需要在这些手机上同时执行相同的操作&#xff0c;这个时候如果能有一种办法批量操作&#xff0c;将会大大提高效率&#xff0c;节省很多时间。本文将介绍基于uiautomator2实现的群控手机方案。 uiautomator2 是 一种 Android 自动化测试框架&…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南

在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...