string的使用(1)

本文是 C++ STL 学习系列的第一篇,从 STL 的整体概念讲起,并以 string 为例梳理常用接口的使用方式,适合刚接触 STL 的读者按顺序阅读。学习 STL 的过程中,接口细节繁多,遇到不确定的函数签名或参数含义时,最可靠的做法是直接查阅官方文档。有关 STL 各组件(容器、迭代器、算法等)的详细说明,可直接查阅 C++ 参考手册。本文只聚焦最常用的部分,力求把「怎么用」讲清楚,把「为什么这样设计」点到为止。

STL库简介

STL(Standard Template Library,标准模板库)是 C++ 标准库的重要组成部分。它不仅是一套可复用的组件库,更是一个涵盖数据结构与算法的通用软件框架。

从设计思想上看,STL 的核心在于泛型编程:通过模板把数据容器与操作算法解耦,使同一套算法能够作用于不同的容器,从而在保证类型安全的同时获得接近手写代码的运行效率。正因如此,STL 被广泛视为 C++ 最具代表性的基础设施之一,也是日常开发中使用频率最高的部分。

string 作为开创 STL 库的先驱,在设计时难免会显得冗余和复杂,这里我们只使用 string 的一些常用接口函数。# string的使用

默认成员函数

这里提供了好几个版本的构造函数和拷贝构造,我们选几个使用一下。

cpp 复制代码
#include<iostream>
#include<string>
using namespace std;

void test1()
{
	string s1;//无参的默认构造
	cout << s1 << endl;
	string s2("hello world");//字符串构造
	cout << s2 << endl;
	string s3("hello world",5);//字符串的一部分构造
	cout << s3 << endl;
	string  s4(s2);//拷贝构造
	//同 string s4 = s2;
	cout << s4 << endl;
	string s5(s2, 0, 5);//用string对象s2的一部分去拷贝构造s5
	cout << s5 << endl;

}

int main()
{
	test1();

	return 0;
}

iterators

迭代器(iterator),目前我们可以理解为是像指针一样的东西,begin 指向的是字符串首字符的地址,end 指向的是字符串末尾,也就是 '\0'。

每个容器中都有一个对应的迭代器,string 类一个迭代器对象的创建方法如下:

cpp 复制代码
	string::iterator it;//通常命名为it或iter

我们可以用一个迭代器去遍历一个字符串。

begin 和 end

cpp 复制代码
string s1("hello world");
string::iterator it1 = s1.begin();
//从头开始遍历
while (it1 != s1.end())
{
	cout << *it1;//类似于指针一样的东西
	it1++;
}
cout << endl;

这是正向迭代,rbegin 和 rend 是用于反向迭代的。

rbegin 和 rend

正向迭代器的类型为iterator,反向迭代器的类型为reverse_iterator。

它们的使用方法和 begin、end 一样,it2 正常往后 ++,就可以达到反向迭代的效果。

cpp 复制代码
string::reverse_iterator it2 = s1.rbegin();
while (it2 != s1.rend())
{
	cout << *it2;
	it2++;
}
cout << endl;

相当于 rbegin 指向的是字符串最后一个字符,rend 指向的是字符串第一个字符的前一个位置。

const迭代器

如果我们不想改变一个迭代器指向的对象的内容,那应该怎么办?

我们直接用 const 修饰迭代器的话,修饰的就是迭代器本身了,迭代器自身都无法修改,如何去迭代一个字符串呢?

所以 const 修饰迭代器的类型为 const_iterator,目的是防止迭代器指向的内容被修改。如果是修饰反向迭代器,则类型为 const_reverse_iterator。

至于后面的 cbegin、cend 等,就是为 const 迭代器提供专门的接口函数,实际上前面四个函数就够用了,这个看个人喜好。

cpp 复制代码
//const迭代器,只用于迭代,防止指向对象的内容被修改
string::const_iterator it3 = s1.begin();
while (it3 != s1.end())
{
	cout << *it3;
	it3++;
}
cout << endl;

string::const_reverse_iterator it4 = s1.rbegin();
while (it4 != s1.rend())
{
	cout << *it4;
	it4++;
}
cout << endl;

Capacity

size

size 是用来返回字符串大小的函数,返回值类型为 size_t,使用无需传参。

cpp 复制代码
string s1("hello");
size_t size = s1.size();
cout << size << endl;

max_size

返回理论上字符串可到达的最大长度,没有任何实际意义。

capacity

返回字符串容量大小的函数。

cpp 复制代码
string s1("hello");
size_t capacity = s1.capacity();
cout << capacity << endl;

clear

用来清空字符串内容的函数。

cpp 复制代码
string s2("hello world");
cout << s2 << endl;
s2.clear();
cout << s2 << endl;

empty

判断字符串是否为空的函数。

reserve

用于扩容的函数,可以通过传一个参数 n 过去指定将字符串容量扩大到 n。如果 n 比字符串原先的容量小,那么这个请求一般是未定义的。如果比字符串原先容量大,那么会扩容到 n 或者一个更合适的容量大小。

cpp 复制代码
string s3("123456");
cout << "capacity:" << s3.capacity() << endl;
//比容量大
s3.reserve(30);
cout << "capacity:" << s3.capacity() << endl;
//比容量小
s3.reserve(20);
cout << "capacity:" << s3.capacity() << endl;

关于 reserve,我们在使用 string 对象的时候,当字符串容量不足时编译器会自动帮我们扩容,每次扩容多大取决于编译器,VS 一般第一次扩容 2 倍,后面每次都扩容为原来的 1.5 倍,但不断扩容在时间效率上会有增加,所以如果我们知道要存多大的字符串,最好先用 reserve 扩容到指定大小,一劳永逸。

resize

用于调整字符串大小的函数。

如文档所示,分为两种情况,第一种是调整后的大小n小于原先的字符串大小_size,则会在字符串第n个字符后进行截断。第二种则是n > _size,为了达到n的大小,字符串第_size个字符之后的字符都用'\0'字符进行补足,如果指定了用c字符进行补足,则会用该字符补足。

cpp 复制代码
string s4("123456");
cout << s4 << endl;
//调整大小比原来字符串小
s4.resize(2);
cout << s4 << endl;
//调整大小比原来字符串大
s4.resize(10);
cout << s4 << endl;
//调整大小比原来字符串大,且指定了填充字符
s4.resize(12, 'x');
cout << s4 << endl;

shrink_to_fit

这是用来给字符串缩容的函数,是 C++11 标准新增的函数。

cpp 复制代码
string s5("123456");
cout << "capacity:" << s5.capacity() << endl;
s5.shrink_to_fit();
cout << "capacity:" << s5.capacity() << endl;
相关推荐
白杨尚青1 小时前
C++进阶篇(六):map 和 set 的模拟实现——用红黑树封装 mymap/myset(迭代器 + operator[])
开发语言·c++·迭代器·stl·set·map·红黑树
kloc4 小时前
聊天室项目入口网关子服务的实现
linux·c++
csdn_aspnet7 小时前
C++ 3个有序点的方向(Orientation of 3 ordered points)
c++·算法
小七在进步8 小时前
string的使用(2)
c++
青少儿编程课堂9 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:折半搜索优化子集枚举(Meet in the Middle)解析
c++·python·算法·bfs·信息学竞赛
wo_jack10 小时前
C++ 入门笔记(十七):list 入门 —— 为什么 list 不能 sort?
数据结构·c++·面试·stl·list
青少儿编程课堂12 小时前
蓝桥杯青少组图形化 + 全国青少年信息素养大赛 + 电子学会Scratch考级:校园连连看解析
c++·python·算法·bfs·信息学竞赛
草莓熊Lotso12 小时前
【C++ 基于微服务的即时通讯系统】文件存储子服务实战:UUID生成、文件IO封装与全接口单元测试
开发语言·网络·数据库·c++·微服务·架构·单元测试
David猪大卫1 天前
【C++修炼】map 和 set 的使用
c语言·开发语言·数据结构·c++·经验分享·笔记·学习