C++ string类相关用法实例

news2024/9/28 7:15:57

前言:

1 string是表示字符串的字符串类
2 string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数,所以string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string
3 使用string类时,必须包含#include<string>头文件以及using namespace std

4 string类对象支持直接用cin和cout进行输入和输出,因为重载了流插入和流提取

在c语言阶段,我们要想输入字符串,首先就需要确定数组的大小,毫无疑问是静态数组

int main()
{
	char str[16];
	scanf("%s", str);
	return 0;
}

固定长度的数组限制了自由,但在c++中string类对象实现了动态增长的数组

int main()
{
	string s;
	cin >> s;
	cout << s;
	return 0;

c++中string类对象可以轻易实现字符串拼接:因为重载了运算符+

int main()
{
	string s("hello ");
	string s2("world");
	string ret = s + s2;
	string ret2 = s + "world";
	cout << ret<<endl<<ret2<<endl;
	return 0;
}

而在c语言中字符串的拼接需要用到strcat,使用十分繁琐,且不会自动扩容 

string类的常用接口
 

1. string类对象的常见构造
 

1 string():默认构造函数,无参,即构造空字符串

2 string (const char* s):用常量字符串初始化string对象

也有另一种写法:

int main()
{
	string s("aaaa");
	string s2 = "aaaa";//二者等价
	return 0;
}

因为单参数的构造函数支持隐式类型的转换:

生成的一个string类型的临时对象用"aaaa"去构造,再将临时对象拷贝构造给s2

构造+拷贝构造--->编译器优化为直接构造 

3 string (size_t n, char c):用n个字符c初始化string对象

4 string (const string& str):拷贝构造函数,用已存在的string对象去拷贝构造新的string对象

 

了解:

 用str对象的一部分去拷贝构造,从pos位置开始取len长度

len给了一个缺省值npos,即当我们没有给len传参时,默认从pos位置开始有多少取多少,也就是一直取到字符串结束

无符号整型的-1是最大值,-1的补码是全1,看成无符号整型就是42亿9千万,也就是4g,但是字符串不会有那么长,所以npos可以看作是有多少取多少,不会越界访问 

也可以用一段迭代器区间去初始化,但是用的不多

int main()
{
	string s("hello");
	string s2(s.begin(), s.end());
	cout << s << endl << s2 << endl;
	return 0;
}

 

赋值:operator=

 2. string类对象的容量操作

 1 size:返回字符串有效字符长度,不包括\0

 

2 capacity:返回分配的存储空间的大小,不包括\0,当此容量耗尽并且需要更多容量时,对象会自动扩展它

 

在vs2019中string对象的初始capacity是15,但实际空间是16,因为要存储\0

不断向string对象去插入数据,容量不够会自动扩容

3 empty:检测字符串是否为空串,是返回true,否则返回false

 

 

4 clear:清空有效字符,但空间还在

 

 

 

5 reserve :为字符串预留空间

在vs2019中,reserve后的空间数,会比原先指定的预留空间数多

在g++中,指定要开多少,reserve就会开多少

那么在我们明确要多少空间的情况下,reserve可以一次性开好空间,避免多次扩容,提高效率,因为扩容是需要付出代价的,尤其是异地扩容

//测试vs2019中string对象的扩容
int main()
{
	string s;
	size_t sz = s.capacity();
	cout << "原本容量: " << sz << endl;
	int i = 0;
	for (i = 0; i < 100; i++)
	{
		s.push_back('A');
		if (sz != s.capacity())
		{
			sz = s.capacity();
			cout << "扩容: " << sz << endl;
		}
	}
	return 0;
}

 所以这时候reserve就有巨大作用了,在你知道需要多少空间的前提下:

int main()
{
	string s;
	s.reserve(100);
	size_t sz = s.capacity();
	cout << "原本容量: " << sz << endl;
	int i = 0;
	for (i = 0; i < 100; i++)
	{
		s.push_back('A');
		if (sz != s.capacity())
		{
			sz = s.capacity();
			cout << "扩容: " << sz << endl;
		}
	}
	cout << s << endl;
	return 0;
}

reserve的使用: 

 

 

在vs2019中reserve参数小于string的底层空间大小时,不会将空间缩小,在标准中,reserve是否会缩小容量,并没有规定:

 

6 resize (size_t n):将有效字符的个数改为n个,多出的用'\0'来填充

resize的参数n分三种情况:

一:n>capacity()  先扩容再插入

二:   size()<n<capacity()  无需扩容直接插入

三:n<size()  删除作用,将有效字符个数size缩短至n

一:插入作用,先扩容再插入,默认插入'\0'

二: 插入作用

resize (size_t n, char c):将有效字符的个数改为n个,多出的用字符c来填充

 

三:删除作用,若是n小于当前字符串长度,则是缩短效果

 元素访问:

string类对象使用运算符[]的重载就很方便,这个访问方式检查越界很严格,一旦越界直接终止程序

也可以用at函数:越界会抛异常,有解决机会,程序不会直接崩掉

有const版本和非const版本

int main()
{
	string s("aaaa");
	s.at(0)++;
	cout << s << endl;
	return 0;
}

 3. string类对象的访问及遍历操作

访问:

operator[]:返回pos位置的字符,const对象和非const对象都可以调用,因为在库中重载了:

​​​​int main()
{
	string s("hello");
	const string s2("Hello");
	cout << s << endl << s2 << endl;

	cout << s[0] << endl << s2[0] << endl;
	s[0] = 'A';
	cout << s << endl;
	//s2[0] = 'S';//不可以修改,因为是const对象
	return 0;
}

 

 string的3种遍历方式:

以下三种方式除了遍历string对象,还可以遍历时修改string中的字符

string类中重载了[],因为string类对象存储字符串的是连续的物理空间,所以可以像遍历普通数组一样,用[]来遍历string,但这种遍历方式并不适配所有容器

1   for+operator[]

int main()
{
	string s("hello");
	size_t i = 0;
	for (i = 0; i < s.size(); i++)
	{
		cout << s[i];
	}
	return 0;
}
 

遍历时修改:

int main()
{
	string s("hello");
	size_t i = 0;
	for (i = 0; i < s.size(); i++)
	{
		s[i]++;
		cout << s[i];
	}
	return 0;
}

 

2 迭代器

迭代器是可以适配所有容器的遍历的,是主流

在string类中,迭代器可以看作是指针,符合访问逻辑

一个string类的对象可以看成有三个成员变量:_str,_size,_capacity

 迭代器iterator都是定义在类域里的,要使用它需要指明类域

int main()
{
	string s("hello");//非const对象的迭代器遍历
	string::iterator it = s.begin();
//也可以用auto自动推导it的类型:
// auto it = s.begin();
	while (it != s.end())
	{
		cout << *it;
		it++;
	}
	cout << endl;
	return 0;
}

 

注意:结束条件不可以写成:it<s.end() 不通用, 在vector,string这种有连续物理空间的容器中是可行的

但是在list中是不可以的,list是一个带头双向循环链表,连接着的节点们的地址之间的大小是未知的,无法比较,所以s.end() 不一定比it大

遍历时修改:

int main()
{
	string s("hello");
	string::iterator it = s.begin();
	while (it != s.end())
	{
		(*it)++;
		cout << *it;
		++it;
	}
	return 0;
}

 

begin:返回指向字符串第一个字符的迭代器

 

非const对象调用非const版本的迭代器,const对象调用const版本的迭代器 

int main()
{
	const string s("hello");//const对象的迭代器遍历
	string::const_iterator it = s.begin();//法一
	//auto it  = s.begin();//自动推导it类型:string::const_iterator 法二
	while (it != s.end())
	{
		cout << *it;
		it++;
	}
	cout << endl;
	return 0;
}

 const对象的迭代器遍历需要调用const的迭代器,那么it的类型就必须是const_iterator

 end:返回最后一个有效字符的下一个位置的迭代器

迭代器反向遍历字符串:

rbegin:返回指向字符串最后一个字符的反向迭代器

rend:返回指向字符串第一个字符的前一个位置的反向迭代器

 

反向迭代器的++是倒着走的,正向迭代器的++是从左往右走,那么方向迭代器的++是从右往左走的 

int main()
{
	 string s("hello");//非const对象的反向遍历
	string::reverse_iterator rit = s.rbegin();
	while (rit != s.rend())
	{
		cout << *rit;
		rit++;
	}
	cout << endl;
	return 0;
}

int main()
{
	const string s("hello");//const对象的反向遍历
	string::const_reverse_iterator rit = s.rbegin();
	while (rit != s.rend())
	{
		cout << *rit;
		rit++;
	}
	cout << endl;
	return 0;
}

总结:迭代器总共有4种,由正向迭代器,反向迭代器,与非const对象,const对象的两两组合 

3 范围for

范围for的底层原理就是迭代器,但是使用更加简洁

注意:范围for不支持倒着遍历

编译器编译时会替换成迭代器

*it会赋值给e

int main()
{
	string s("hello");
	for (auto e : s)
	{
		cout << e;
	}
	cout << endl;
	return 0;
}

 遍历时修改:

因为底层原理是迭代器,*it会赋值给e,e只是*it的一份拷贝,对e做修改是改变不了原字符串的

&e,e就是*it的别名,就可以对原字符串进行修改了

int main()
{
	string s("hello");
	for (auto &e : s)
	{
		e++;
		cout << e;
	}
	cout << endl;
	return 0;
}

 4. string类对象的修改操作

push_back (char c):在字符串后尾插字符c

int main()
{
	string s("hello");
	s.push_back('A');
	cout << s << endl;
	return 0;
}

 

append:

 

int main()
{
	string s("hello ");
	string s2("world");
	s.append(s2);
	cout << s << endl;
	return 0;
}

int main()
{
	string s("hello ");
	s.append("world");
	cout << s << endl;
	return 0;
}

 

int main()
{
	string s("hello ");
	s.append(10,'A');
	cout << s << endl;
	return 0;
}

 

operator+=:

int main()
{
	string s("hello ");
	string s2("world");
	s += s2;
	cout << s << endl;
	return 0;
}

int main()
{
	string s("hello ");
	s += "world";
	cout << s << endl;
	return 0;
}

 

int main()
{
	string s("hello ");
	s += 'A';
	cout << s << endl;
	return 0;
}

 

 assign:

为字符串分配一个新值,替换其当前内容

int main()
{
	string s("aaaaaaaaaaaaaaaaaa");
	string s2("bbb");
	s.assign(s2);
	cout << s << endl;
	return 0;
}

insert:

 

 在pos位置之前插入

int main()
{
	string s("hello");
	s.insert(0, 1, 'C');//头插
	s.insert(s.begin(), 'C');//头插
	cout << s << endl;
	return 0;
}

erase:

 第一个接口比较常用,但是无论是erase还是insert都要少用,因为涉及挪动数据,效率低


int main()
{
	string s("hello");
	s.erase(1);
	cout << s << endl;
	return 0;
}

replace:

接口设计复杂繁多,需要时再去查一下文档即可

替换字符串的一部分

int main()
{
	string s("hello world");
	s.replace(5, 1, "%20");
	cout << s << endl;
	return 0;
}

 replace同样涉及挪动数据的问题,效率低

刷题过程中可能会碰到过以下一个题目:将字符串中的所有空格替换成%20

可以用find函数找到空格+replace替换,但是效率很低,所以可以采用以下方法:

int main()
{
	string s("hello world hello world");
	string s2;
	for (auto e : s)
	{
		if (e != ' ')
		{
			s2 += e;
		}
		else
		{
			s2 += "%20";
		}
	}
	//s = s2;法一
	//s.assign(s2);法二
	s.swap(s2);//法三
	cout << s << endl;
	return 0;
}

让s中的字符串变成s2中的字符串有如上三种方式,法一法二都是赋值

法三的效率相较于法一法二提高不少,原因如下:

string类的对象中可以看成是这样的结构:_str  _size  _capacity

s.swap(s2) 交换的是双方的_str

证明:

int main()
{
	string s("hello world hello world");
	string s2;
	for (auto e : s)
	{
		if (e != ' ')
		{
			s2 += e;
		}
		else
		{
			s2 += "%20";
		}
	}
	cout << "交换前:"<<endl;
	cout <<(void*)s.c_str() << endl;//c++char*的打印比较特殊,需要强转为其他类型,否则打印的是字符串形式的内容
	cout << (void*)s2.c_str() << endl;
	s.swap(s2);//法三
	cout << "交换后:"<<endl;
	cout << (void*)s.c_str() << endl;
	cout << (void*)s2.c_str() << endl;
	cout << s << endl;
	return 0;
}

 

 其实也可以直接用swap函数,不过此swap不是库里的swap,而是string类中的全局swap

 

对于库中的swap函数模板,和string类中现成的全局swap函数,会优先调用string类中的全局swap函数 ,效率就和调用成员函数swap一样高

所以其实有三个swap:

库中的swap:是一个函数模板

 若是用库中的swap完成两个string类对象的交换,代价比较大,要完成一次拷贝构造,两次赋值

所以string类中设计了一个全局的swap:

它的行为就像调用string类对象的成员函数swap一样,效率很高 

string类中的成员函数swap:

c_str:

返回c格式字符串

int main()
{
	string s("hello ");
	cout<<s.c_str()<<endl;
	cout << s << endl;
	return 0;
}

find:

 pos的缺省值为0,默认从头开始找,pos若是给定值,则从给定位置开始查找

 返回值:

返回第一个匹配项的第一个字符的位置。
如果未找到匹配项,则该函数返回 string::npos

find通常可以substr搭配使用:

实例1:如取后缀

int main()
{
	string s("test.cpp");
	size_t i = s.find('.');
	string s2 = s.substr(i);
	cout << s2 << endl;
	return 0;
}

 

 实例2:分割网址的协议、域名、资源名

int main()
{
	string s("https://legacy.cplusplus.com/reference/string/string/rfind/");
	string sub1;
	string sub2;
	string sub3;

	size_t i1 = s.find(':');
	if (i1 != string::npos)
	{
		sub1 = s.substr(0, i1);
	}
	else
	{
		cout << "找不到" << endl;
	}

	size_t i2 = s.find('/', i1 + 3);
	if (i2 != string::npos)
	{
		sub2 = s.substr(i1 + 3, i2 - (i1 + 3));
	}
	else
	{
		cout << "找不到" << endl;
	}

	sub3 = s.substr(i2 + 1);
	cout << sub1 << endl;
	cout << sub2 << endl;
	cout << sub3<< endl;
	return 0;
}

1.

int main()
{
	string s("hello ");
	string s2("hello world");
	size_t pos = s.find(s2);
	if (pos == string::npos)
	{
		cout << "找不到" << endl;
	}
	else
	{
		cout << pos << endl;
	}
	return 0;

int main()
{
	string s("aaaaahello ");
	string s2("hello ");
	size_t pos = s.find(s2);//默认从头开始查找
	if (pos == string::npos)
	{
		cout << "找不到" << endl;
	}
	else
	{
		cout << pos << endl;
	}
	return 0;
}

 

 2 

int main()
{
	string s("aaaaahelloworld");
	size_t pos = s.find("world");//默认从头开始查找
	if (pos == string::npos)
	{
		cout << "找不到" << endl;
	}
	else
	{
		cout << pos << endl;
	}
	return 0;
}

3

int main()
{
	string s("helloworld");
	size_t pos = s.find('e');//默认从头开始查找
	if (pos == string::npos)
	{
		cout << "找不到" << endl;
	}
	else
	{
		cout << pos << endl;
	}
	return 0;
}

rfind:

 从字符串的后面开始向前查找

如有多个后缀,要取到最后一个后缀:

int main()
{
	string s("test.cpp.tar.zip");
	size_t i = s.rfind('.');
	string s2 = s.substr(i);
	cout << s2 << endl;
	return 0;
}

 

如果未找到匹配项,则该函数返回 string::npos 

int main()
{
	string s("worldworld");
	size_t pos = s.rfind("world");//默认从尾开始查找
	if (pos == string::npos)
	{
		cout << "找不到" << endl;
	}
	else
	{
		cout << pos << endl;
	}
	return 0;
}

substr:

 从pos位置开始截取len个字符生成子串

 若是len没有传参,则从pos位置开始,截取pos位置及之后的所有内容

int main()
{
	string s("hello world");
	string str = s.substr(6);
	cout << str << endl;
	return 0;
}

int main()
{
	string s("hello world");
	string str = s.substr(6,3);
	cout << str << endl;
	return 0;
}

getline:

获取一行

 不论是cin还是scanf遇到空格或者换行就会停止读取

所以当一行字符串中有空格时,用cin是无法完整读取到的,但是getline是获取一行,它可以做到,除此之外,若是给getline传你指定的分隔符,那么就可以以你想要的方式读取结束

 

输入:

以'!'结束读取

 5. string类非成员函数

operator+:

能少用这个运算符重载就少用,传值返回,且有多次拷贝的代价

int main()
{
	string s;
	string ret1 = s + '#';
	string ret2 = s + "world";

	cout << ret1 << endl;
	cout << ret2 << endl;
	return 0;
}

operator>>:

输入运算符重载

operator<<:

输出运算符重载

relational operators:

比较大小

 6. vs和g++下string结构的说明

vs下string的结构
 

看下面一段代码,试猜一下在32位平台下vs中,一个string类的对象的大小是多少呢?

int main()
{
	string s;
	cout << sizeof(s) << endl;
	string s2("hello world");
	cout << sizeof(s2) << endl;
	return 0;
}

string总共占28个字节
 

string内部有一个联合体,联合体用来定义string中字符串的存储空间:

union _Bxty
{ // storage for small buffer or pointer to larger one
	value_type _Buf[_BUF_SIZE];
	pointer _Ptr;
	char _Alias[_BUF_SIZE]; // to permit aliasing
} _Bx;


1 当字符串长度小于16时,使用内部固定的字符数组来存放

2 当字符串长度大于等于16时,从堆上开辟空间
 

因为大多数情况下字符串的长度都小于16,那string对象创建好之后,内
部已经有了16个字符数组的固定空间,不需要通过堆创建,效率高
 

实际上,vs中一个string类对象的真实结构如下:

 _buff[16]

_str

_size

_capacity

16+3*4 = 28

其中的字符数组_buff共有16个空间,能存储有效字符的空间个数是15,剩下的一个要存储'\0'

所以,当字符串长度小于16时,存储到buff数组里面

当字符串长度大于等于16时,存储到_str指向的空间里

实例:

int main()
{
	string s("aaaaaa");
	string s2("hello world1111111111111111111111");
	return 0;
}

 

g++下string的结构
 

写时拷贝(了解):

写时拷贝是在浅拷贝的基础之上增加了引用计数的方式来实现的

用string类的s1去拷贝构造s2,若是浅拷贝

 

浅拷贝的问题:1 析构两次 2 一个对象的修改会影响另一个对象

问题1的解决:增加一个变量,引用计数,拷贝的时候++引用计数,析构的时候先--引用计数,引用计数减到0时说明是最后一个对象,可以释放空间,否则不释放空间,因为还有其他对象在使用这块空间

 

 

问题2的解决:写时拷贝(全称是引用计数的写时拷贝,写的时候再拷贝,即延迟拷贝)

 当要对空间上的数据进行修改且不能影响其他对象时,需要深拷贝

引用计数的写时拷贝的意义:在只是浅拷贝的基础上,如果没有修改,那就很赚了,没有开空间,没有深拷贝 

G++下,string是通过写时拷贝实现的,32位平台下,string对象总共占4个字节,64位平台下,string对象总共占8个字节,内部只包含了一个指针,该指针将来指向一块堆空间,内部包含了如下字段:

1 容量 2 字符串有效字符个数 3 引用计数

struct _Rep_base
{ 
    size_type      _M_length;//容量
    size_type      _M_capacity;//有效字符个数
    _Atomic_word   _M_refcount;//引用计数
};

4 用于存储字符串的空间

 存储n个有效字符,表面上是开n个空间,实际上需要开n+12+1个空间

实例:g++下的写时拷贝

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

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

相关文章

【漏洞修复】OpenSSH-ssh-agent 越权访问CVE-2023-38408

CVE-2023-38408漏洞升级ssh版本 漏洞说明修复步骤RPM包编译 漏洞说明 漏洞名称&#xff1a;OpenSSH-ssh-agent 存在越权访问漏洞影响范围&#xff1a;ssh-agent(-∞, 9.3-p2) openssh(-∞, 9.3p2-1)漏洞描述&#xff1a;SSH-Agent是SSH的一部分&#xff0c;它是一个用于管理私…

设计模式之享元模式(Flyweight)的C++代码实现

1、享元模式提出 面向对象很好地解决了抽象问题&#xff0c;但是创建对象会带来一定的内存开销。绝大部分情况下&#xff0c;创建对象带来的内存开销是可以忽略不计的&#xff1b;在有些情况下是需要谨慎处理的&#xff0c;如类A的sizeof是50个字节&#xff0c;则创建50*1024*…

AIGC:从入门到精通

一、前言 相信一部分的人在看到本活动的主题是关于AIGC的时候&#xff0c;都会存在疑惑--到底什么是AIGC呢&#xff1f;故本文主要介绍关于AIGC的基本内容&#xff0c;全部内容采用自己搭建的ChatGPT模型生成&#xff0c;具体内容如下&#xff1a; 本文章&#xff0c;参与&…

互联网医院|申办互联网医院这些资质不能少

互联网医院作为一种创新的医疗模式&#xff0c;正在以其便捷、智能、人性化的特点改变着人们的生活方式和医疗体验。它以数字化技术和合作共赢的精神&#xff0c;打开了医疗的新纪元。让我们共同期待&#xff0c;互联网医院将为健康事业带来更多机遇和挑战&#xff0c;引领着健…

Spyglass 脚本

Spyglass小白可以使用Gui界面进行debug Spyglass检查(一)作为IC设计人员&#xff0c;熟练掌握数字前端语法检查工具Spyglass的重要性不言而喻&#xff0c;本文讲解景芯SoChttps://mp.weixin.qq.com/s/fp07o-AvaQvLT79Di0Tb7A 熟悉电路和软件之后可以使用脚本完成整个流程 sp…

【分享】使用FileChannel进行文件拷贝

前言: 项目实际编写中&#xff0c;使用到了多种文件拷贝方式&#xff0c;有包括专门使用c写了拷贝工具&#xff0c;供给Java调用&#xff0c;也有使用标准的输入输出流&#xff0c;这里分享的是借助 FileChannel 来读写,nio中传送数据使用channelbuffer&#xff0c;大的数据可以…

第九章 动态规划part09(代码随想录)

198.打家劫舍 题目&#xff1a; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。…

图的顺序存储结构

目录 图的顺序存储结构 图的顺序存储结构C语言实现 图的邻接表存储结构详解 邻接表计算顶点的出度和入度 图的十字链表存储结构 图的邻接多重表存储结构 图的顺序存储结构 使用图结构表示的数据元素之间虽然具有“多对多”的关系&#xff0c;但是同样可以采用顺序存储&a…

网络通信原理总结(第五十二课)

网络通信原理 结构目录 1 TCP/IP协议追层分析物理层(第三十九课)_IHOPEDREAM的博客-CSDN博客 2 网络通信TCP/IP协议逐层分析数据链路层(第四十课)_IHOPEDREAM的博客-CSDN博客 3 网络通信原理数据链路层&数制转换(第四十一课)_IHOPEDREAM的博客-CSDN博客 4 网络通信原理…

[LeetCode]矩阵对角线元素的和

解题 思路 1: 循环,找到主对角线的下标和副对角线的下标,如果矩阵长或宽为奇数的时候,需要减去中间公共的那一个值,中间公共的那个数的下标为mat[mat.size()/2][mat.size()/2]副对角线的下标为 mat [i][mat.size()-i-1] class Solution { public:int diagonalSum(vector<ve…

一文读懂|Linux 虚拟文件系统(VFS)

前言 虚拟文件系统是一个很庞大的架构&#xff0c;如果要分析的面面俱到&#xff0c;会显得特别复杂而笨拙&#xff0c;让人看着看着&#xff0c;就不知所云了&#xff08;当然主要还是笔者太菜&#xff09;&#xff0c;所以这篇博客&#xff0c;以 open() 函数为切入点&#…

2020年3月全国计算机等级考试真题(C语言二级)

2020年3月全国计算机等级考试真题&#xff08;C语言二级&#xff09; 第1题 有以下程序 void fun1 (char*p) { char*q; qp; while(*q!\0) { (*Q); q&#xff1b; } } main() { char a[]{"Program"},*p; p&a[3]; fun1(p); print…

英语学习 Eudic欧路词典 for Mac

欧路词典是一款功能强大的英语学习工具&#xff0c;其多语种支持、海量词库、强大的翻译功能、听力训练和生词本和笔记等特点&#xff0c;使得用户可以方便地进行英语学习和提高英语水平&#xff0c;适用于各种英语学习人员和文化交流人员等不同人群。 1 、全面支持最新Retina…

Salesforce Winter ‘24即将发布!亮点功能抢先看

随着Winter 24脚步的临近&#xff0c;一波增强功能即将面世&#xff0c;Trailblazers的期望值越来越高。在这片云计算的海洋里&#xff0c;一些亮点功能总能在生态系统中引起巨大轰动。 Winter 24发布日期 Winter 24发布的具体日期取决于您的Salesforce实例&#xff0c;主要日…

vue echarts macd指标 完整代码

1 逻辑 给指定的series两个对象 两个对象有相同的xAxisIndex: 2,yAxisIndex: 2, 不同的data {name: "",type: "line",data: data1,xAxisIndex: 2,yAxisIndex: 2,},{name: "",type: "bar",data: data2,xAxisIndex: 2,yAxisIndex: 2,},…

爱荷华州的一个学区正在使用ChatGPT来决定禁止哪些书籍

为了响应爱荷华州最近颁布的立法&#xff0c;管理员们正在从梅森市学校图书馆移除禁书&#xff0c;官员们正在使用ChatGPT帮助他们挑选书籍&#xff0c;根据公报和大众科学. 由州长金雷诺兹签署的禁令背后的新法律是教育改革浪潮的一部分&#xff0c;共和党立法者认为这是保护…

滑块验证码-接口返回base64数据

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言所需包图片示例使用方法提示前言 滑动验证码在实际爬虫开发过程中会遇到很多,不同网站返回的数据也是千奇百怪。这里分享一种接口返回base64格式的情况以及处理方式 所需包 opencv-python、…

【LangChain】Feature Store 特征库 一种新型存储方式 —— 功能存储

Feature Store 特征库 特征库的主要目的是什么&#xff1f;特征库的五个主要组件组成一&#xff1a;Serving 服务组成二&#xff1a;Storage 存储组成三&#xff1a;Transform 转换组成四&#xff1a;Monitoring 监控组成五&#xff1a;Feature Registry 功能注册表 Feature St…

简单学习MySQL

最近&#xff0c;再看数据库相关的知识&#xff0c;用不着学太深&#xff0c;先学一些基本知识&#xff0c;以后需要的时候有个基础&#xff0c;不至于像个无头苍蝇&#xff0c;我学习的网站如下&#xff08;MySQL 教程 | 菜鸟教程 (runoob.com)&#xff09; 对MySQL的介绍 My…

[oneAPI] 手写数字识别-VAE

[oneAPI] 手写数字识别-VAE oneAPIVAE模型实现手写数字识别任务定义使用包定义参数加载数据VAE模型与介绍训练过程结果 比赛&#xff1a;https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Intel DevCloud for oneAPI&#xff1a;https://devcloud.intel.com/one…