模板初阶、auto关键字、范围for和string类的使用

news2024/12/28 11:52:13

目录

1. 模板初阶

1.1 泛型编程

1.2 函数模板

1.3 类模板

2. auto关键字

3. 范围for的使用(略提)

4. String类部分接口的使用

4.1 String构造函数的使用

4.2 string类begin和end的使用

4.3 string类的rbegin和rend的使用

4.4 string类的size和length的使用

4.5 string类的resize和capacity的使用

4.6 string类的shrink_to_fit的使用

4.7 string类的reserve的使用

4.8 string类[]的使用

4.9 string类的at的使用

4.10 string类的front和back的使用

4.11 string类operator+=、append、push_back的使用

4.12 string类的c_str、find和npos、和rfind的使用


1. 模板初阶

1.1 泛型编程

  •  起源: 在平常如果说我们想写Swap来交换两个变量,那么如果说每次都传入不同的变量那么就需要通过重载函数来实现,例如我们要交换两个int变量,那就需要写一个SwapInt()函数,如果要交换两个char变量,那就需要些一个SwapChar()函数,这样太麻烦了,为了解决这个问题C++就提出了泛型编程。
  • 泛型编程:泛型编程是一种编写与类型无关的代码,是代码复用的一种手段,例如提供一个图案的模板给你然后你可以印出不同颜色但图案是一样的图形;而模板就是泛型编程的基础如下图所示:

1.2 函数模板

  • 函数模板的概念:函数模板就代表了上图的一个图案的模板,你可以传入不同的类型的值来产生特定类型的版本;
  • 函数模板的语法:template<class T1, class T2, ......class Tn>或者template<typename T1, typename T2, ....... typename Tn>;class和typename都可以使用。
  • 函数模板的原理:函数模板并不是一个函数,它就像一张给编译器创建不同类型函数的蓝图,你需要int就传入int,需要char就传入char,通俗点来说就是让编译器当🐮🐴,不需要程序员当牛马了;如下图所示:                         在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应 类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演, 将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。
  • 函数模板的实例化:用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化 和显式实例化。
  • 隐式实例化:传入实参,让推演模板参数的实际类型;如下代码所示:
    template<typename T>
    void Swap(T& left, T& right)
    {
    	T temp = left;
    	left = right;
    	right = temp;
    }
    
    int main()
    {
    	//实际上调用的是两个函数
    	int a = 1, b = 2;
    	cout << "a is >" << a << endl;
    	cout << "b is >" << b << endl;
    	Swap(a, b);
    	cout << "After Swap a is >" << a << endl;
    	cout << "After Swap b is >" << b << endl;
    
    	double c = 1.6, d = 2.0;
    	cout << "c is >" << c << endl;
    	cout << "d is >" << d << endl;
    	Swap(c, d);
    	cout << "After Swap c is >" << c << endl;
    	cout << "After Swap d is >" << d << endl;
    	return 0;
    }
    

    👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

    运行结果为:

  • 显示实例化:意思就是需要手动给予类型,语法:函数名<类型>(参数);为什么要加入这个语法呢?因为如果说一个函数的参数没有T类型的话那么编译器就无法推导出T的类型,那时候我们就需要显示实例化的使用;如下代码所示:

    #include<iostream>
    using namespace std;
    
    template<typename T>
    T* func(size_t n)
    {
    	return new T[n];
    }
    
    int main()
    {
    	int a1 = 10, a2 = 20;
    	double d1 = 10.0, d2 = 20.0;
    	
    	//显示实例化
    	//意思就是明确给明了T的类型就是<>里面的类型;
    	//必须显示实例化的场景
    	//这里由于参数没有T的类型,所以我们传参数时
    	//编译器无法推出T是什么类型 那么这个时候我们就
    	//需要显示实例化的使用
    	//func(10);
    	func<int>(10);
    	func<double>(29);
    	return 0;
    }

  • 模板参数的匹配原则:如果说同时出现两个Add,一个是模板,一个是int类型的时候,我们在下面调用它Add(1 , 3);并不会出现两个都调用的情况,而是调用原有的Add函数;这其实就像是你在家里肚子饿了的时候有两个选择,第一个是点外卖(调用已有的Add),第二个是自己做(调用模板),那肯定会选择点外卖,那如果说家长指定(显示实例化)让你要自己做(调用模板),那就得自己去做饭(调用模板);如下代码所示:

    //模板参数的匹配机制
    #include<iostream>
    using namespace std;
    
    int Add(int left, int right)
    {
    	return left + right;
    }
    
    // 通用加法函数
    template<class T>
    T Add(T left, T right)
    {
    	return left + right;
    }
    
    template<class T1, class T2>
    T1 Add(T1 left, T2 right)
    {
    	return left + right;
    }
    
    int main()
    {
    	//有的人就说会不会这两个会有冲突,因为两个都是Add(int left, int right)
    	//但实际上用模板生成的int类型的函数和Add是不一样的
    	Add(1, 2);//这里肯定是调用Add函数,有现成的不会调用模板
    	Add<int>(2, 3);//指定<>了的话就会调用模板
    
    	Add(1.3, 1.9);//两个同类型的会先调用同类型的template<class T>
    	Add(1, 1.9);//template<class T1, class T2>
    	return 0;
    }
  • 注意:模板生成的int函数和你创建的int的函数不一样,这个需要通过汇编才能看到;如下图所示:call那里调用的是不同的函数

1.3 类模板

  • 类模板的定义格式:
    template<class T1, class T2, ..., class Tn>
    class 类模板名
    {
    // 类内成员定义
    };
    //typedef 和template的区别
    #include<iostream>
    using namespace std;
    
    //本来说可以用typedef 来代替类模板,但是其实不是的
    //如果说我们想同时创建多个不同类型的类的时候用typedef是
    //无法实现的,但是我们可以用template类模板实现,例如
    Stack<int> st1;
    Stack<double> st2;
    //但是typedef 无法实现
    
    
    using STDatetype = int;  //这个可以平替typedef
    typedef int STDatetype;
    
    
    
    //注意Stack是类名
    // Stack<int>才是类型
    // 类模版
    template<typename T>
    class Stack
    {
    public:
    	Stack(size_t capacity = 4)
    	{
    		_array = new T[capacity];
    		_capacity = capacity;
    		_size = 0;
    	}
    	void Push(const T& data);
    private:
    	T* _array;
    	size_t _capacity;
    	size_t _size;
    };
    
    //类模板类外声明需要这样;
    //声明和定义分离的写法
    template<class T>
    void Stack<T>::Push(const T& data)
    {
    }
    
    int main()
    {
    	//这里类模板必须是用显式实例化
    	//实例化生成对应的类,这里是两个不同类型
    	Stack<int> st1;
    	Stack<double> st2;
    
    	return 0;
    }
    
  • 注意:类模板的实例化,类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类

2. auto关键字

  • auto是可以根据初始化的值来推导类型,那样的话就代表auto类型在创建变量的时候必须初始化,如果不初始化编译后就不知道他是什么类型;如下代码所示:
    void TheUseAuto()
    {
    	//auto 关键字的使用,auto是可以就是根据初始化的值来推导类型
    	int a = 10;
    	double b = 3.1415;
    	auto c = a;
    	auto d = b;
    	cout << "c is:>" << c <<endl;
    	cout << "d is:>" << d <<endl;
    }

    👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

    运行结果为:

  • 用auto声明指针类型的时候,用auto和auto*没有任何区别,但用auto声明引用类型的时候必须加&;

  • auto不能作为函数的参数,可以做返回值,但是建议谨慎使用
  • auto不能直接用来声明数如下代码所示:
    // 可以做返回值,但是建议谨慎使用
    auto func1()
    {
    	return 3;
    }
    int main()
    {
    	int a = 10;
    	auto b = a;
    	auto c = 'a';
    	auto d = func1();
    
    	// 编译报错:rror C3531: “e”: 类型包含“auto”的符号必须具有初始值设定项
    	auto e;
    	cout << typeid(b).name() << endl;
    	cout << typeid(c).name() << endl;
    	cout << typeid(d).name() << endl;
    	int x = 10;
    	auto y = &x;
    	auto* z = &x;
    	auto& m = x;
    	cout << typeid(x).name() << endl;
    	cout << typeid(y).name() << endl;
    	cout << typeid(z).name() << endl;
    	auto aa = 1, bb = 2;
    
    	// 编译报错:error C3538: 在声明符列表中,“auto”必须始终推导为同一类型
    	auto cc = 3, dd = 4.0;
    
    	// 编译报错:error C3318: “auto []”: 数组不能具有其中包含“auto”的元素类型
    	auto array[] = { 4, 5, 6 };
    	return 0;
    }

  • 在这里看不出auto的魅力,auto实际上就是一块语法糖;当我们学到string类后,string类中有一个 叫迭代器(iterator)其实就先当做是一个指针,首先先用string类实例化一个对象s1,那每次定义一个迭代器的时候就需要写:---string :: iterator lt1 = s1.begin();但我们可以使用auto来解决这点,直接auto lt1 = s1.begin();

    	string s3("hello world");
    	string::iterator lt3 = s3.begin();
    	cout << "Befor -1, s3 is:> " << s3 << endl;
    	while (lt3 != s3.end())
    	{
    		//这里是让hello world的ascii码值全部-1
    		(*lt3)--;
    		lt3++;
    	}
    	cout << "After -1, s3 is:> " << s3 << endl;
    	cout << endl;

    👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

    运行结果为:


3. 范围for的使用(略提)

直接看代码和里面注释;😊

void TheUseFor()
{
	//现在来讲的是For范围的使用
	//对于一个有范围的集合而言要是让程序员自己说明循环范围的时候如果出现一些粗心则会发生错误
	//为了避免这个情况C++11引入了For范围的使用
	//使用语法For(类型: 变量)如下
	//而且这也是传入起始位置然后他就会自行遍历
	string str("i love sleeping");
	for (auto temp : str)
	{
		cout << temp << " ";
	}
	cout << endl;

	//使用for范围遍历对str2进行修改
	string str2("hello world");
	for (auto& temp : str2)
	{
		temp += 2;
	}
	for (auto temp : str2)
		cout << temp << " ";
	cout << endl << endl;	

	//这里说明了其实for循环和for范围是一样的
	//但for范围其实也就是一种语法糖,主打一个方便
	int a[] = { 1,2,3,4,5,6 };
	for (size_t i = 0; i < sizeof(a)/sizeof(int); i++)
	{
		cout << a[i] << " ";
	}
	cout << endl;

	for (auto e : a)
	{
		cout << e << " ";
	}
	cout << endl;

}

👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:

4. String类部分接口的使用

4.1 String构造函数的使用

具体链接:string::string - C++ Reference (cplusplus.com)

#include<string>
using namespace std;
int main()
{
	//string 类构造使用

	//copy
	string s1 = "leoweitao1222";
	string s2(s1);
	cout << "The use of copy:> " << s2 << endl;

	//substring(取子串)
	string s3 = "Congratulation!!!";
	string s4(s3, 4, 6);
	cout << "The use of substring:> " << s4 << endl;

	//c-string
	char arr[] = "klasjdklafj";
	string s5(arr);
	cout << "The use of c-string:> " << s5 << endl;
	return 0;
}

 👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:


4.2 string类begin和end的使用

  • begin这是一个返回首元素地址,需要用迭代器接收 具体链接:string::begin - C++ Reference (cplusplus.com)

	//begin
	string s1("hello mynameislwt");
	//配合迭代器使用
	string::iterator it1 = s1.begin();
	while (it1 != s1.end())
	{
		cout << *it1 << " ";
		it1++;
	}

 👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:                    


  • end是一个返回尾部元素地址的,需要用迭代器接收;具体链接:string::end - C++ Reference (cplusplus.com)

		string str("Test string");
		for (auto it = str.begin(); it != str.end(); ++it)
		{
			cout << *it << " ";
		}

👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:

4.3 string类的rbegin和rend的使用

rbegin和rend就是倒过来的意思,本来begin是返回首元素的迭代器,但是rbegin就是从后面开始算起,颠倒过来了,rbegin的迭代器指向的其实就是end指向的前一个元素;(注意:end指向的是尾部元素的后一个位置)

具体链接:string::rbegin - C++ Reference (cplusplus.com)

	//逆序rbegin其实就是尾部,需要通过++到达rend处
	string s1("hello leowhytool");
	string::reverse_iterator it1 = s1.rbegin();
	while (it1 != s1.rend())
	{
		cout << *it1 << " ";
		it1++;
	}

👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:

!!!rend也一样就不重复说了;


4.4 string类的size和length的使用

size 和length的作用效果是一样的,实际上一个是stl里的一个是string里面的,length是string里自带的,但是这个只在物理内存连续的情况下适用例如数组的长度等,但是不能用在树上,因为树没有长度,只有大小;

具体链接:string::size - C++ Reference (cplusplus.com)

	//size 和length的作用效果是一样的,实际上一个是stl里的
	//一个是string里面的,length是string里自带的,但是这个只在物理内存连续的情况下适用
	//例如数组的长度等,但是不能用在树上,因为树没有长度,只有大小;
	string s1("hello leowhytool");
	cout << s1.size();

👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:


4.5 string类的resize和capacity的使用

resize就是修改size的大小,capacity就是返回他那个空间的容量,如果超过capacity的大小的话,那就会进行扩容;注意!:size是返回string的长度;

具体链接:string::resize - C++ Reference (cplusplus.com)

	string s1("hello leowhytool12333");
	s1.resize(10);
	cout << "s1.size is :> " << s1.size() << endl;
	cout << s1 << endl;
	cout << "s1.capacity is:> " << s1.capacity() << endl;

	s1.resize(20, 'a');
	cout << "s1.size is :> " << s1.size() << endl;
	cout << s1 << endl;
	cout << "s1.capacity is:> " << s1.capacity() << endl;

👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:


4.6 string类的shrink_to_fit的使用

shrink_to_fit就是让capacity的空间适配size的空间,例如capacity开了100个空间,但只使用了10个,size就为10,然后我们使用shrink_to_fit就可以让capacity最大程度接近10,而减少空间浪费;

具体链接:string::shrink_to_fit - C++ Reference (cplusplus.com)


	//shiring_to_fit的使用:其实我们给s1增容的时候会多加空间的,具体就看capacity
	//和size的大小就可以知道
	string s1(100,'q');
	cout << "The size of s1 is:> " << s1.size() << endl;
	cout << "The capacity of s1 is:> " << s1.capacity() << endl;
	
	//如果我们不用shrink_to_fit的话当我们使用了resize后capacity不会因此而改变
	//那么如果说我们resize了20后,capacity还有100个那么就会造成80个空间浪费,那么
	//我们就可以使用shrink_to_fit 让 capacity适配size
	s1.resize(20);
	s1.shrink_to_fit();
	cout << "After shrink,the size of s1 is:> " << s1.size() << endl;
	cout << "After shrink,the capacity of s1 is:> " << s1.capacity() << endl;

👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:


4.7 string类的reserve的使用

reserve的中文意思是保留,而在C++里其实就是提前为字符串预留出空间来,可以减少动态申请内存时对性能损耗的情况,这个是当你在知道需要多少空间的时候可以使用,可以不用进行动态申请内存;而一般使用reserve的话,当你要申请100个空间的时候他可能会给你申请111个,这都是正常的;打个比方,当找父母要95块钱时大多数父母都会直接凑整给个100;

	string s1("leowhytool");
	cout << "The capacity of s1 is:> " << s1.capacity() << endl;
	s1.reserve(100);
	cout << "After the reserve,the capacity of s1 is:> " << s1.capacity() << endl;

👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:


4.8 string类[]的使用

string类里已经重载了[],使得我们可以通过[]访问指定的元素,就类似数组通过下标访问指定位置的元素一样,非常方便;

具体链接:string::operator[] - C++ Reference (cplusplus.com)

	string s1("leowhytool");
	cout << s1[1] << endl;
	cout << endl;
	for (int i = 0; i < s1.length(); ++i)
	{
		cout << s1[i];
	}
	cout << endl;	

👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:


4.9 string类的at的使用

at就是返回指定位置的字母,我们通过at来修改指定位置的字符,因为at的返回值是引用;

具体链接:string::at - C++ Reference (cplusplus.com)

	//at的使用,就是取到指定位置的字母,我们可以修改他,因为返回值是引用
	string s1("hello, leowhytool");
	cout << s1.at(3) << endl;
	s1.at(3) = 'q';
	cout << s1 << endl;

👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:


4.10 string类的front和back的使用

front顾名思义就是取string的首位元素,而back就是取string的最后一位元素;我们都可以通过他俩来修改string的首位元素和最后一位元素,因为他俩的返回值类型都是引用;

back具体链接:string::back - C++ Reference (cplusplus.com)

front具体链接:string::front - C++ Reference (cplusplus.com)

	//back()的使用:就是取到最后一个,因为返回值是引用所以我们可以对其进行修改
	//front就是取最前面字母
	string s1("hello,lewowhytool");
	cout << s1.back() << endl;
	s1.back() = 'e';
	cout << s1 << endl;

	cout << s1.front() << endl;
	s1.front() = 'q';
	cout << s1 << endl;

👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:


4.11 string类operator+=、append、push_back的使用

  • operator+=:string类重载了+=,可以很好的实现尾插一串字符串和尾插一个字符;

具体链接:string::operator+= - C++ Reference (cplusplus.com)

	//operator+=
	string s1("i love ");
	s1 += 'a';
	cout << s1 << endl;

	s1 += " hamburger";
	cout << s1 << endl;

👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:

  • append:其实和operator+=一样,都是在后面尾插一段字符串;但append的用法很多,具体的看文案使用,这里就演示两种;

具体链接:string::append - C++ Reference (cplusplus.com)

	//append 在尾部插入一段
 string s1("i love ");
	s1.append("hamburger");
	cout << s1 << endl;

	//这个是插入str2的一部分字符串
	string str("i love ");
	string str2("hamburger");
	cout << str.append(str2, 0,3) << endl;

👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:

  • push_back尾插操作,这个尾插只是单纯尾插一个字符;

具体链接:string::push_back - C++ Reference (cplusplus.com)

	
	//push_back 尾插操作
	string str3("i love ");
	str3.push_back('g');
	cout << str3 << endl;

👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:

4.12 string类的c_str、find和npos、和rfind的使用

  • c_str的作用是直接返回一个指向字符串的指针

具体链接:string::c_str - C++ Reference (cplusplus.com)icon-default.png?t=O83Ahttps://legacy.cplusplus.com/reference/string/string/c_str/

	string s1("i love hamburger");
	const char* str1 = s1.c_str();
	for (int i = 0; i < strlen(str1); i++)
	{
		cout << str1[i] << " ";
	}

👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:

  • find和npos:find和npos一起使用,npos其实就是string的最大容量,但是在编译器中是无法生成这个大小的空间的,所以我们可以通过find和npos的使用达到从头遍历到尾的效果

具体链接:string::npos - C++ Reference (cplusplus.com)

具体链接:string::find - C++ Reference (cplusplus.com)

void TestFind()
{
	string s1("qqqqqqqqqqqqqqqqqqqqqqqqq");
	cout << "s1's npos is:> " << s1.npos << endl;

	string str1 = "i love hamburger, but i dont love apple";
	string str2 = "love";
	size_t Found = str1.find(str2);
	if (Found != str1.npos)
	{
		cout << "第一次是在:" << Found << "出现" << endl;
	}
	//这里其实就是让他跳过第一个找到love的l的位置去到o,然后又接着去找后面再次出现love的位置
	//所以这里需要Found+1
	Found = str1.find(str2, Found + 1);
	if (Found != str1.npos)
	{
		cout << "第二是在:" << Found << "出现" << endl;
	}
}

👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:

  • rfind就是找到最后一次出现的那个字符;

具体链接:string::rfind - C++ Reference (cplusplus.com)

void TestRfind()
{
	string s1("我想吃汉堡,我不想吃苹果");
	string s2("想");
	size_t find = s1.rfind(s2);
	if (find != s1.npos)
	{
		s1.replace(find, s2.size(), " ");
	}
	cout << s1 << endl;
}

👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇  👇

运行结果为:


END!

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

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

相关文章

使用 npkill 快速清理本地 node_modules 文件

npkill 可以直接在终端可视化的清除 本地 node_modules 文件夹&#xff0c;方便我们即使清除不常用的依赖。 直接在终端执行 npx npkill 即可开启 node_modules 本地扫描&#xff1a; 然后&#xff0c;我们选择不需要的 node_modules 按下空格即可删除。

sentinel2 L2A处理基线04.00 反射率计算方法

sentinel2 处理基线04.00发布后&#xff0c;L2A地表反射率计算方式也发生了调整&#xff1b;根据新版的数据说明&#xff0c;新版数据增加了负值偏移。因此计算时需要读取数据产品中MTD_MSIL2A.xml的元文件。注意&#xff0c;相比之前的版本&#xff0c;元文件中增加了BOA_ADD_…

django创建一个新的应用

使用 python manage.py startapp myapp 命令可以在你的 Django 项目中创建一个新的应用&#xff0c;名为 myapp。应用是 Django 项目的组成部分&#xff0c;可以帮助你组织代码和功能。执行该命令后&#xff0c;会在你的项目目录下创建一个名为 myapp 的文件夹&#xff0c;包含…

docker部署minio文件服务器

1. 拉取镜像 docker search minio docker pull minio/minio2. 创建映射 mkdir -p /root/docker_app/minio_data mkdir -p /root/docker_app/minio_config3. 执行docker run 自定义用户和秘钥安装: admin/admin123456 docker run -p 9000:9000 -p 9001:9001 -d --name mini…

JavaScript 可视化案例详解

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

大模型驱动的自主智能体全面调研

人工智能咨询培训老师叶梓 转载标明出处 基于LLMs构建的自主智能体&#xff0c;有望实现类似人类的决策能力。图 1 展示了LLMs驱动的自主智能体领域的增长趋势。从2021年1月到2023年8月&#xff0c;不同颜色代表不同类别的智能体。例如&#xff0c;游戏智能体旨在模拟游戏玩家…

MySQL那些事(InnoDB架构和存储结构)

目录 一、序言二、InnoDB架构三、InnoDB内存结构1、Buffer Pool (缓冲池)2、Change Buffer3、Log Buffer 四、InnoDB磁盘结构1、表空间2、Doublewrite Buffer(双写缓冲区)3、Redo Log4、Undo Log 五、结语 一、序言 本节内容为博主根据MySQL 8.0版本官方文档手动翻译过后的最新…

pycharm 配置篇

方法注释 使用方式为&#xff0c;在方法名下方输入三个双&#xff08;单&#xff09;引号&#xff0c;回车&#xff0c;自动生成。五种风格的样式如下&#xff1a; def docstrings_func_plain(parm_a, parm_b, parm_c):"""Plain 风格"""def docs…

笔记本电脑如何改ip地址:操作指南与注意事项

在信息时代的浪潮中&#xff0c;网络已成为我们日常生活与工作中不可或缺的一部分。对于笔记本电脑用户而言&#xff0c;IP地址作为设备在网络中的唯一标识&#xff0c;其重要性不言而喻。无论是出于网络安全、网络测试还是特殊网络环境等需求&#xff0c;了解如何修改笔记本电…

NVIDIA Hopper 架构深入

NVIDIA Hopper 架构 GPU 的重要新功能。 文章目录 一、Transformer engine 变压器发动机二、第四代 NVLink 和 NVLink 网络三、第三代 NVSwitch四、New NVLink Switch System 新的 NVLink 开关系统五、PCIe Gen 5 PCIe 第 5 代一、Transformer engine 变压器发动机 Transforme…

java给word设置复选框

poi设置 使用"Wingdings 2" 字体 WordUtil.appendText(paragraph, "\uF052", "Wingdings 2",null); WordUtil.appendText(paragraph, "□", null);选中的复选框: poi导出pdf的时候正常使用aspose-words导出pdf就空了 使用默认字体…

给自己的项目(vue3)中添加 下雪/樱花飘落的背景

查看更佳效果前往我的博客&#xff0c; 可切换 snows_ls BLOGhttp://124.223.41.220/ 0、效果图 樱花飘落 雪花飘落 1、安装 yarn add jparticles / npm i jparticles 2、引入 import { Snow } from jparticles; // 引入粒子效果库 引入雪花效果库 3、使用 在项目中的app.…

onnx TRT 版本对应关系

Onnx 版本和opset 关系 https://github.com/onnx/onnx/blob/main/docs/Versioning.md Onnx runtime 对应 onnx opset 版本 Compatibility | onnxruntime Tensor RT 和onnx 支持版本可以看如下并选择对应分支 https://github.com/onnx/onnx-tensorrt/blob/release/8.4-GA/doc…

企业内训|AI助力智能办公与职场效能提升-青岛某国资平台

9月25日&#xff0c;TsingtaoAI派驻讲师进驻现场&#xff0c;为青岛市某国资平台公司员工交付“AI助力智能办公与职场效能提升”企业内训&#xff0c;整个培训通过AIGC的实际应用案例&#xff0c;帮助学员掌握智能办公的常用工具&#xff0c;提升工作流程优化和决策效率。课程涵…

衡石分析平台系统管理手册-智能运维之软件授权

软件授权​ 在设置->软件授权页面可以看到授权时间、有效期、用户上限、请求码、租户数上限、租户内用户数上限。 请求码是衡石系统用于生成注册码的一段代码&#xff0c;安装衡石系统后&#xff0c;就会自动生成一个请求码&#xff0c;其中包含了本机的指纹信息和当前 Lic…

BFS 解决 FloodFill 算法

BFS 解决 FloodFill 算法 题目一&#xff1a; 图像渲染1. 题⽬链接&#xff1a;2. 题⽬描述&#xff1a;3. 算法思路&#xff1a;4.代码 题目二&#xff1a; 岛屿数量1. 题⽬链接&#xff1a;2. 题⽬描述&#xff1a;3. 算法思路&#xff1a;4.代码 题目三&#xff1a;被围绕的…

Android Stuido中编译信息出现乱码的解决方式

打开菜单File -> Settings&#xff0c;选择Editor -> File Encodings 窗口&#xff0c;将编码设置为正确的字符集&#xff0c;保证 Global Encoding、Project Encoding 和 Default Encoding for properties files 都设置为 UTF-8。

物联网(二)——MDPI特刊推荐

特刊征稿 01 期刊名称&#xff1a; Application of IoT on Manufacturing, Communication and Engineering 截止时间&#xff1a; 摘要提交截止日期&#xff1a;2025年4月30日 投稿截止日期&#xff1a;2025年6月30日 目标及范围&#xff1a; 感兴趣的主题包括但不限于以…

Python输入输出

1、输出 python中变量的输出&#xff0c;print 会自动在行末加上回车,如果不需回车&#xff0c;只需在print语句的结尾添加一个逗号”,“ 1.1、普通输出 print(hello)1.2、格式化输出 1.2.1、使用%来格式化 格式化符号大全 符 号描述%c格式化字符及其ASCII码%s格式化字符…

Visual Studio C# 编写加密火星坐标转换

Visual Studio C# 编写加密火星坐标转换 1、WGS84坐标转GCJ02火星坐标2、GCJ02火星坐标转WGS84坐标&#xff08;回归计算&#xff09;3、GCJ02火星坐标转BD09百度坐标4、BD09百度坐标转GCJ02火星坐标&#xff08;回归计算&#xff09;5、坐标公共转换类6、地图显示7、程序简单界…