C++入门第六篇---STL模板---string【上】string模板的介绍(下)

简介: C++入门第六篇---STL模板---string【上】string模板的介绍(下)
3.empty函数:

返回字符串是否为空,是则为true,反之返回false.

4.clear函数:

清空字符串,它的实现原理其实就是在下标为0的位置放一个\0,由于要迁就C语言的关系,C++也同样识别到\0停止,所以我们下标为0的位置放入\0,就相当于字符串被清空了(但同时也别忘了改变_size=0),不过注意capacity一般是不轻易改变的,但size是实时改变的

5.reserve函数:

注意reserve调整的是capacity而不是size,别看混了

6.resize函数:

改变的是size,而不是capacity,同时,我们这里不仅可以调整size,对于多开的位置,我们可以指定字符char c放入。

7.shrink_to_fit函数:

缩容空间的作用,不过多赘述,它可以缩容capacity让其和对应的size匹配到一起

细节问题:

容量操作类的细节理解:

1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
2. clear()只是将string中有效字符清空,不改变底层空间大小,也就是说不改变capacity的大小
3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。

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

1.operator[]string下标访问赋值重载函数:

通过这个函数,我们就可以向访问数组下标一样访问字符串的元素内容。

学会了这个函数之后,我们就可以这样遍历字符串:

string d1("hbw66");
int i=0;
for(i=0;i<d1.size();i++)
{
      cout<<d1[i]<<" ";
}
2.begin end函数:(cbegin cend就是const 版本的begin end)

看到上面的图片,我们会很疑惑它这里的iterator是什么呢?其实,这里的iterator便是迭代器类型的变量的意思,而在这里,begin会返回指向第一个元素位置的迭代器变量,而end会返回最后一个元素的下一个元素位置的迭代器变量,即\0的位置。

所以下面让我们先介绍一下迭代器:

补充迭代器的知识点!!!!:

迭代器关键字iterator,迭代器类型的本质实际上是一种指针,但它是string里面的一个内部类,要通过string域限定符去访问,即string::iterator it,迭代器适用于各种容器模板的场景,这一点是要比我们上面的单纯遍历更加的适用。由于迭代器就跟指针一样,故迭代器也需要解引用才能访问或者修改里面的具体元素。

迭代器完全体现了面向对象的封装,根据不同的适用情况去适配不同的迭代器,常见的string迭代器在这里有四种:

1.const_iterator:const的string类迭代器
2.const_reverse_iterator:const类的翻转string迭代器
3.reverse_iterator:非cosnt类的翻转迭代器
4.iterato:正常迭代器

由于迭代器前面的限制需要注意的太多,我们可以用auto自动识别类型同时简化代码,这样不会误判类型,让auto自动去匹配对应的类型。

由此,我们就可以这样遍历字符串了:

string d1("hello world");
auto it=d1.begin();
while(it!=d1.end())
{
    cout<<*it<<" ";
    it++;
}

通过对迭代器的解引用和操作,从而实现遍历的效果,还记得我们之前说过的范围for么?本质上,范围for可以实现++,向后走的功能就是通过迭代器,故范围for本质上就是通过迭代器来实现的,范围for在调用代码时,其实本质上调用的就是迭代器遍历,这一点是可以检验的,在后面我们模拟实现string模板的时候我会再提及。

3.rbegin rend函数 (crbegin crend):

相当于反向遍历字符串,其他的使用方式和begin end相同,本质上也是返回迭代器。

4.at函数:

这里的at函数作用和[]运算符重载一样,但唯一的不同是,at发生越界时会抛异常,故我们需要try catch接收,而[]则是直接报错终止掉程序,相当于assert断言的效果

4.字符串操作修改类:

1.push_back函数:

在字符串中尾插一个字符,注意根据函数,它只能尾插字符不能尾插字符串

2.append函数:

在字符串中尾插一个字符串,根据函数参数的书写,我们可以插一整个字符串,也可以根据需要只尾插一部分或者指定长度的字符串的一部分,也可以插一个string类

3.operator+=运算符重载函数(尾插最常用的一个!!!):

功能相当于push_back和append的合体,更加简便和适用,所以为什么说STL模板很复杂冗余呢?明明有+=这样好的,再写一个push_back和append意义不大。

4.operator+函数:

这里不过多赘述,就是对原字符加上字符从而创建一个新的字符串,但同时原字符不发生改变。

5.assign函数:

把assign里面的一部分赋值给接收值,但接收值之前的数据会被覆盖,可以控制长度

6.insert函数:

在指定位置的前面插入,可以插一个字符,也可以插一个字符串,或者一个string类,同时还可以指定个数的插入

7.erase函数:

在指定位置删除,可以指定长度,或者指定迭代器,或者指定删除的范围

8.replace函数:

可以在指定位置替换插入字符或者字符串的函数,它可以指定替换单个字符,也可以在单个字符的位置直接替换插入一整个字符串:

如下:

string d1("hello world");
d1=d1.replace(3,"hbw040115");
cout<<d1<<endl;

这样,打印出来的结果就是helhbwo4o115 world。

但由于涉及到挪动数据的问题,erase insert replace这三种函数都是不提倡使用的,因为太影响效率了

9.c_str函数:

以C语言的方式返回字符串,也就是说结尾是带\0的,这是C++兼容C语言的体现。

10.swap函数:

用来交换两个字符串的this和str的函数,本质上就是交换这两个字符串的地址赋给对应的指针,让this的指针指向str的位置,str的指针指向this的位置

swap中还封装了一个全局函数swap,即this不是隐藏的而是正正好好写出来的两个string参数,这个时候一旦调用可能会涉及到深拷贝的问题,故通过这个全局函数swap,让用户无论怎样调用都是这个类里面的函数,提高了效率

5.find查找系列:

1.find函数(rfind就是倒着找的函数,用法和find没事区别,但是从末尾开始):

找到指定的符号在字符串中的对应位置,并且返回这个位置对应的下标,如果找不到,就返回npos即极大长度值

2.substr函数:

将指定下标之间的元素返回给一个string类,这个函数一般配合find使用,可以起到分割字符串的作用如下:

hbw::string d2("http://www.google.com/feference/peffect/friend/");
  hbw::string sub1, sub2, sub3;
  size_t i1 = d2.find(':');
  if (i1 ==d2.getnpos())
  {
    cout << "没有找到i1" << endl;
  }
  else
  {
    sub1 = d2.substr(0, i1);
  }
  size_t i2=d2.find('/',i1+3);
  if (i2 == d2.getnpos())
  {
    cout << "没有找到i2" << endl;
  }
  else
  {
    sub2 = d2.substr(i1 + 3,i2-(i1+3));
  }
  sub3 = d2.substr(i2 + 1, d2.size() - (i2 + 1));
  cout << sub1 << endl;
  cout << sub2 << endl;
  cout << sub3 << endl;

在这里,它可以将网址分隔开三个部分。

3.find_first_of /find_last_of/find _first_not_of/find_last_not_of函数:

fing_first_of用来从头找字符串中是否有指定的字符,并返回下标,而last则到着找,而带not的则是反过来,找字符串中不是指定字符的字符并返回其下标,last同理也是倒着找.

6.其他重要函数类:

1.getline函数:

getline是可以重新设置字符串的结束标志的函数,它默认会直接识别读取到一行结束,无视空格,一旦用户指定符号,就一直读到指定符号后结束,这个很关键,在oj题里使用C++很常用

2.operator>> /opeerator<<流插入流提取的运算符重载:

不多赘述,模拟实现时我们详解,在这里我们先知道,它可以让string类型也使用<< >>符号输入输出字符串,十分方便

3.relational operators比较大小运算符重载函数:

用来比较两个字符串大小的函数,其实现大致利用了strcmp函数,对于这一系列运算符重载函数,可以让我们对于string类也可以使用内置类型的操作符,更加方便。

只需要注意其实现的时候,运算符重载多用复用实现即可,这个后续在模拟实现的时候我会演示。

总结:

以上便是我们string模板的介绍和一些函数用法的解析,下一篇文章中我们将进一步模拟实现这些函数,从而让我们进一步理解他们的用法,想要熟练使用STL库,我们需要多多刷题反复使用这些函数,自然而然就记住了,对于一些不常见的我们直接查文档,记不住也不要焦虑,那意味着并不常用,我们只需要明确STLstring库中有这个东西,到时候直接查看使用即可。

目录
相关文章
|
6月前
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
163 2
|
6月前
|
存储 算法 C++
【c++丨STL】map/multimap的使用
本文详细介绍了STL关联式容器中的`map`和`multimap`的使用方法。`map`基于红黑树实现,内部元素按键自动升序排列,存储键值对,支持通过键访问或修改值;而`multimap`允许存在重复键。文章从构造函数、迭代器、容量接口、元素访问接口、增删操作到其他操作接口全面解析了`map`的功能,并通过实例演示了如何用`map`统计字符串数组中各元素的出现次数。最后对比了`map`与`set`的区别,强调了`map`在处理键值关系时的优势。
311 73
|
3月前
|
存储 算法 安全
c++模板进阶操作——非类型模板参数、模板的特化以及模板的分离编译
在 C++ 中,仿函数(Functor)是指重载了函数调用运算符()的对象。仿函数可以像普通函数一样被调用,但它们实际上是对象,可以携带状态并具有更多功能。与普通函数相比,仿函数具有更强的灵活性和可扩展性。仿函数通常通过定义一个包含operator()的类来实现。public:// 重载函数调用运算符Add add;// 创建 Add 类的对象// 使用仿函数return 0;
111 0
|
3月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
78 0
|
3月前
|
存储 安全 编译器
c++入门
c++作为面向对象的语言与c的简单区别:c语言作为面向过程的语言还是跟c++有很大的区别的,比如说一个简单的五子棋的实现对于c语言面向过程的设计思路是首先分析解决这个问题的步骤:(1)开始游戏(2)黑子先走(3)绘制画面(4)判断输赢(5)轮到白子(6)绘制画面(7)判断输赢(8)返回步骤(2) (9)输出最后结果。但对于c++就不一样了,在下五子棋的例子中,用面向对象的方法来解决的话,首先将整个五子棋游戏分为三个对象:(1)黑白双方,这两方的行为是一样的。(2)棋盘系统,负责绘制画面。
41 0
|
6月前
|
编译器 C++
模板(C++)
本内容主要讲解了C++中的函数模板与类模板。函数模板是一个与类型无关的函数家族,使用时根据实参类型生成特定版本,其定义可用`typename`或`class`作为关键字。函数模板实例化分为隐式和显式,前者由编译器推导类型,后者手动指定类型。同时,非模板函数优先于同名模板函数调用,且模板函数不支持自动类型转换。类模板则通过在类名后加`&lt;&gt;`指定类型实例化,生成具体类。最后,语录鼓励大家继续努力,技术不断进步!
|
6月前
|
存储 分布式计算 编译器
C++入门基础2
本内容主要讲解C++中的引用、inline函数和nullptr。引用是变量的别名,与原变量共享内存,定义时需初始化且不可更改指向对象,适用于传参和返回值以提高效率;const引用可增强代码灵活性。Inline函数通过展开提高效率,但是否展开由编译器决定,不建议分离声明与定义。Nullptr用于指针赋空,取代C语言中的NULL。最后鼓励持续学习,精进技能,提升竞争力。
|
6月前
|
存储 算法 C++
【c++丨STL】set/multiset的使用
本文深入解析了STL中的`set`和`multiset`容器,二者均为关联式容器,底层基于红黑树实现。`set`支持唯一性元素存储并自动排序,适用于高效查找场景;`multiset`允许重复元素。两者均具备O(logN)的插入、删除与查找复杂度。文章详细介绍了构造函数、迭代器、容量接口、增删操作(如`insert`、`erase`)、查找统计(如`find`、`count`)及`multiset`特有的区间操作(如`lower_bound`、`upper_bound`、`equal_range`)。最后预告了`map`容器的学习,其作为键值对存储的关联式容器,同样基于红黑树,具有高效操作特性。
240 3
|
3月前
|
存储 编译器 C语言
关于string的‘\0‘与string,vector构造特点,反迭代器与迭代器类等的讨论
你真的了解string的'\0'么?你知道创建一个string a("abcddddddddddddddddddddddddd", 16);这样的string对象要创建多少个对象么?你知道string与vector进行扩容时进行了怎么的操作么?你知道怎么求Vector 最大 最小值 索引 位置么?
76 0
|
6月前
|
缓存 安全 Java
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
137 11