C++知识整理day5容器——string容器

0.前置知识–STL简介

STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。
STL的六大组件:
在这里插入图片描述
我们之前在数据结构阶段学了很多,包括顺序表、链表、栈、队列、二叉树等等;在之后我们在做算法题时,需要用到哪个数据结构,靠我们手写是不太现实的,C++帮我们封装了很多的容器,本质上他们都是给我们实现好的一个个类,我们直接使用即可。当然我们也要学习他的底层,这是很重要的。
本节我们先来学习一下string类。这里有个小知识点,其实string类是不属于STL里的容器的。因为string类的出现是比容器早很多的,因为需要频繁使用字符串。所以string类在设计的时候,不是设计的很好。
在这里插入图片描述
string类的内容大概是这样,有size,也有capacity,当然里面有很多的成员方法。(其实里面也有buffer数组,了解一下)

1.为什么要学习string类?

C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。比如说strcpy,我们必须有足够的空间让他来拷贝,他的空间大小是固定的,不想string,他的本质就是一个类,是可以自动扩容的。

2.auto关键字和范围for

2.1 auto关键字

  1. 使用auto修饰的变量,是具有自动存储器的局部变量,后来这个不重要了。C++11中,标准委员会变废为宝赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。

  2. 用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
    在这里插入图片描述

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

  4. auto不能作为函数的参数,可以做返回值,但是建议谨慎使用
    在这里插入图片描述
    在这里插入图片描述

  5. auto不能直接用来声明数组
    在这里插入图片描述
    Q:写了类型本来就不费事,还要使用auto干什么?
    A:等到后面写容器迭代器的,就会很好用。

2.2 范围for

  1. 对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围,自动迭代,自动取数据,自动判断结束。
  2. 范围for可以作用到数组和容器对象上进行遍历
  3. 范围for的底层很简单,容器遍历实际就是替换为迭代器,这个从汇编层也可以看到

示例:

int a[5] = {
   
    1, 2, 3, 4 ,5 };
	for (auto x : a)
	{
   
   
		cout << x << ' ';
	}
	cout << endl;

注意:上面我们写的是auto x : a 其底层是将数组a对应下标的值赋值给x,x只是一个临时拷贝的对象,改变x的值不会影响到数组a,我们若是想改变数组a的值,我们就需要使用引用的概念,示例:
在这里插入图片描述

3.string类常用的接口

推荐大家去C++的官网学习对应的接口:https://cplusplus.com/

3.1 string类对象常见的构造

构造函数名称 功能说明
string s 构造空的string类对象s,即空字符串
string(const string& s) 拷贝构造函数
string(const string& str, size_t pos, size_t len = npos) 从字符串str上,从下标pos开始拷贝npos个字符
string(const char* s) 用C-string来构造string类对象
string(size_t n, char c) string类对象中包含n个字符c
string (const char* s, size_t n) 从C-string中拷贝前n个字符

注:这里解释一下npos,npos默认值是-1,即拷贝到字符串str的末尾,当npos大于字符串长度时不会报错,会拷贝完这个字符串。npos是一个静态成员变量,他的类型是size_t。

示例:

string s1();//构造一个空的字符串
	string s2("hello world!");//用C-string来构造string对象
	string s3(s2);//拷贝构造
	string s4(s2, 6);//npos默认值是-1
	string s5("hello world", 5);//拷贝前五个字符
	string s6(5, 'x');
	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	cout << s4 << endl;
	cout << s5 << endl;
	cout << s6 << endl;

在这里插入图片描述

3.2 string类对象的访问

函数名称 功能说明
operator[pos] 返回pos位置的字符,即下标访问
at(pos) 返回pos位置的字符
back() 返回最后一个元素
front() 返回第一个元素

示例:

string s("hello world");
	for (int i = 0; i < s.size(); i++)
	{
   
   
		cout << s[i];
	}
	cout << endl;
	for (int i = 0; i < s.size(); i++)
	{
   
   
		cout << s.at(i);
	}
	cout << endl;

	cout << "s.front():" << s.front() << endl;
	cout << "s.back():" << s.back() << endl;

在这里插入图片描述
Q:使用下标[]和at()有什么区别吗?
A:对于访问字符串,如果越界了的话,[]会直接报错,终止程序运行,而at可以通过抛异常来解决,示例:

在这里插入图片描述
对于at()访问越界的字符串,我们只要通过捕异常就可以让程序继续运行。
在这里插入图片描述
而通过下标[]来获取越界的字符,会直接终止程序。

3.3 string类对象的遍历–迭代器

通过上面下标的方式也可以遍历字符串,这里我们主要讲解一下通过迭代器来遍历。

Q:既然下标可以遍历,为什么还要使用那么复杂的迭代器来遍历?
A:对于这种顺序结构我们当然优先使用下标来遍历,但是对于像链表这样非顺序结构的,那我们那就只能通过迭代器来遍历链表啦。

函数名称 功能说明
begin + end begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
rbegin + rend 反向遍历的
cbegin + c
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值