【C++进阶(一)】STL大法以及string的使用

简介: 【C++进阶(一)】STL大法以及string的使用

1. 前言

由于C语言的标准库不够强大

没有数据结构和一些基本算法

什么都需要程序员自己实现

所以C语言在某种意义上并不实用


本章重点:

本章会简单介绍STL的各个版本
STL的六大组件和怎样学STL
STL的缺陷
重点讲解string的使用
熟悉string的重要接口
目标是讲完能够独自使用string库


2. STL库的版本以及缺陷

STL的版本:

  • 原始版本
    Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原始版本一样做开源使用。 HP 版本–所有STL实现版本的始祖。
  • P. J. 版本
    由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用,不能公开或修改,缺陷:可读性比较低,符号命名比较怪异。
  • RW版本
    由Rouge Wage公司开发,继承自HP版本,被C+ + Builder 采用,不能公开或修改,可读性一般。
  • SGI版本
    由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版 本。被GCC(Linux)采用,可移植性好,可公开、修改甚至贩卖,从命名风格和编程 风格上看,阅读性非常高。我们后面学习STL要阅读部分源代码主要参考的就是这个版本

比较重要的是P.J版和SGI版
一个被Windows系统采用
一个被Linux系统采用

STL库的缺陷:

  1. STL库的更新太慢了。
    这个得严重吐槽,上一版靠谱是C++98,中间的C++03基本一些修订。C++11出来已经相隔了13年,STL才进一步更新。
  2. STL现在都没有支持线程安全。
    并发环境下需要我们自己加锁。且锁的粒度是比较大的。
  3. STL极度的追求效率,导致内部比较复杂。比如类型萃取,迭代器萃取。



3. STL库的六大组件

请看下图:

后期对于STL的学习将按照以下顺序:

  • 进阶内容:
    各种算法
    string vector
    list stack
    queue deque
    priority_queue
    仿函数
  • 高阶内容:
    map和set
    AVL数和红黑树
    哈希相关

4. string的使用

首先,所有的STL库函数的使用都要查看

C++字典来学习接口函数,并且模拟实现

先看string解释(不懂可以翻译)

简单来说,string是表示字符串的字符串类
该类的接口与常规容器的接口基本相同
再添加了一些专门用来操作string的常规操作


4.1 string类对象常见构造

一共有七个构造函数,但实用的有下面5个

  1. 用一个字符串构造
string str("abcdefg");
  1. 用一个字符构造
string str('w');
  1. 用n个字符c构造
string str(10,'x');
  1. 用一段迭代器区间构造
string tmp("abcdefg");
string str(tmp.begin(),tmp.end());
  1. 拷贝构造
string tmp("abcdefg");
string str(tmp);

注:迭代器类似于指针,在string和
vector中,迭代器就是普通指针
在后期会介绍迭代器的概念


5. string类对象的容量操作

请看下图:

string的内部实现中有size

和capacity两个和容量相关的变量

size代表字符串有效长度

capacity代表字符串的实际长度


5.1 size和capacity接口函数

size和capacity函数比较简单

可自行查看接口函数的返回值,参数

使用方法:

string str("abcdefg");
int size = str.size();
int capacity = str.capacity();

切记要加上括号!

size和capacity是成员函数

.或者->访问


5.2 empty和clear函数

empty函数十分简单

若类对象是空串,就返回true

若不是空串就返回false

clear需要注意的点:

  • clear后,使用empty会返回true
  • clear函数只将size清零
  • clear函数不会改变capacity

5.3 resize和reserve函数

resize函数需要注意的点:

  • 此函数既能改变size也能改变capacity
  • 在不初始化的情况下直接将size扩为n
  • 将size扩为n并且用n个字符c初始化

reserve函数需要注意的点:

  • 此函数只改变capacity不改变size

6. 迭代器以及string的访问和遍历

迭代器: iterator

像指针一样的类型,用法和指针相似

  • 函数begin返回第一个位置的迭代器
  • 函数end返回size位置的迭代器

迭代器的使用:

string str("abcdefg");
string::iterator it = str.begin();
while(it != str.end())
{
  cout<<*it<<endl;
  it++;
}

迭代器可以像指针一样++和–

也可以解引用拿到指向的内容


6.1 运算符重载[ ]

它可以让我们像使用数组一样

随机访问string类对象中的字符

比如:

string str ("Test string");
 for (int i=0; i<str.size(); ++i)
 {
   cout << str[i];
 }

并且string类会检查[]是否越界

  • string不喜欢用迭代器,因为[]更好用
  • vector也不喜欢用迭代器,[]更好用
  • list不能用[],因为它不支持随机访问

6.2 反向迭代器和范围for

反向迭代器: reverse_iterator

顾名思义是倒着走的迭代器

和反向迭代器相对应的是

rbegin和rend函数

使用方法:

string s("abcdefg");
string::reverse_iterator rit = s.rbegin();
while(rit != s.rend())
{
  cout<<*rit;
  rit++;
}

rit++是往前走,会打印gfedcba

支持了迭代器后就可以使用范围for遍历:

string str("abcdefg");
for(auto ch : str)
{
  cout<<ch;
}

7. string类对象的修改操作

首先,npos是int的最大值

append不常用,+=很常用!

push_back使用:

string str("abcde");
str.push_back('f');
str.push_back('g');
//str现在是:abcdefg

接口函数:operator+=

此函数可以+=一个字符或一个字符串
甚至是一个string类对象:

string tmp("hij");
string str("abc");
str+='d';
str+="efg";
str+=tmp;
//str现在为:abcdefghij

7.1 c_str和find函数

c_str函数返回字符串从\0结尾的字符串

但是c++中的字符串不一定以\0结尾

c++中字符串类以size为准来结尾

所以它叫:c_str,是c语言的规则

下面这段代码可以自己理解一下:

string filename("test.cpp");
cout << filename << endl;
cout << filename.c_str() << endl;
filename += '\0';
filename += "string.cpp";
cout << filename << endl; // string 对象size为准
cout << filename.c_str() << endl; // 常量字符串对象\0

find函数比较简单

大家阅读文档就应该知道这是啥意思


8. insert和erase函数

insert函数可以在pos位置插入

一个字符或者一个字符串或者

一个string类,甚至还可以指定插入

字符串的长度,接口很多,需要自己理解

erase函数可以删除从pos位置

往后len个字符,若erase函数全用

缺省参数,则从0位置删除npos个

也就是将字符全部删除完

甚至可以删除一段迭代器区间


9. 总结以及拓展

string类需要我们单独拿出来学习

这是因为STL库函数中很多接口

都是相似的,学习了string后

会对vector和list等等容器的学习有帮助

vector的接口函数:

不能说和string一模一样
只能说和string完全相同

大家有兴趣可以自行去搜vector和list

拓展题目以及阅读

学完string后可以尝试做一下简单题:

拓展阅读

string类的operator<</ operator>>/ getline


🔎 下期预告:vector的接口函数 🔍


目录
打赏
0
0
0
0
18
分享
相关文章
【c++丨STL】list模拟实现(附源码)
本文介绍了如何模拟实现C++中的`list`容器。`list`底层采用双向带头循环链表结构,相较于`vector`和`string`更为复杂。文章首先回顾了`list`的基本结构和常用接口,然后详细讲解了节点、迭代器及容器的实现过程。 最终,通过这些步骤,我们成功模拟实现了`list`容器的功能。文章最后提供了完整的代码实现,并简要总结了实现过程中的关键点。 如果你对双向链表或`list`的底层实现感兴趣,建议先掌握相关基础知识后再阅读本文,以便更好地理解内容。
31 1
【c++丨STL】list的使用
本文介绍了STL容器`list`的使用方法及其主要功能。`list`是一种双向链表结构,适用于频繁的插入和删除操作。文章详细讲解了`list`的构造函数、析构函数、赋值重载、迭代器、容量接口、元素访问接口、增删查改操作以及一些特有的操作接口如`splice`、`remove_if`、`unique`、`merge`、`sort`和`reverse`。通过示例代码,读者可以更好地理解如何使用这些接口。最后,作者总结了`list`的特点和适用场景,并预告了后续关于`list`模拟实现的文章。
55 7
【c++丨STL】vector的使用
本文介绍了C++ STL中的`vector`容器,包括其基本概念、主要接口及其使用方法。`vector`是一种动态数组,能够根据需要自动调整大小,提供了丰富的操作接口,如增删查改等。文章详细解释了`vector`的构造函数、赋值运算符、容量接口、迭代器接口、元素访问接口以及一些常用的增删操作函数。最后,还展示了如何使用`vector`创建字符串数组,体现了`vector`在实际编程中的灵活性和实用性。
104 4
【c++丨STL】string模拟实现(附源码)
本文详细介绍了如何模拟实现C++ STL中的`string`类,包括其构造函数、拷贝构造、赋值重载、析构函数等基本功能,以及字符串的插入、删除、查找、比较等操作。文章还展示了如何实现输入输出流操作符,使自定义的`string`类能够方便地与`cin`和`cout`配合使用。通过这些实现,读者不仅能加深对`string`类的理解,还能提升对C++编程技巧的掌握。
105 5
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
80 2
【c++丨STL】vector模拟实现
本文深入探讨了 `vector` 的底层实现原理,并尝试模拟实现其结构及常用接口。首先介绍了 `vector` 的底层是动态顺序表,使用三个迭代器(指针)来维护数组,分别为 `start`、`finish` 和 `end_of_storage`。接着详细讲解了如何实现 `vector` 的各种构造函数、析构函数、容量接口、迭代器接口、插入和删除操作等。最后提供了完整的模拟实现代码,帮助读者更好地理解和掌握 `vector` 的实现细节。
50 0
|
14天前
|
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
55 19
【C++面向对象——类与对象】CPU类(头歌实践教学平台习题)【合集】
声明一个CPU类,包含等级(rank)、频率(frequency)、电压(voltage)等属性,以及两个公有成员函数run、stop。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。​ 相关知识 类的声明和使用。 类的声明和对象的声明。 构造函数和析构函数的执行。 一、类的声明和使用 1.类的声明基础 在C++中,类是创建对象的蓝图。类的声明定义了类的成员,包括数据成员(变量)和成员函数(方法)。一个简单的类声明示例如下: classMyClass{ public: int
39 13
【C++面向对象——继承与派生】派生类的应用(头歌实践教学平台习题)【合集】
本实验旨在学习类的继承关系、不同继承方式下的访问控制及利用虚基类解决二义性问题。主要内容包括: 1. **类的继承关系基础概念**:介绍继承的定义及声明派生类的语法。 2. **不同继承方式下对基类成员的访问控制**:详细说明`public`、`private`和`protected`继承方式对基类成员的访问权限影响。 3. **利用虚基类解决二义性问题**:解释多继承中可能出现的二义性及其解决方案——虚基类。 实验任务要求从`people`类派生出`student`、`teacher`、`graduate`和`TA`类,添加特定属性并测试这些类的功能。最终通过创建教师和助教实例,验证代码
38 5
【C++面向对象——群体类和群体数据的组织】实现含排序功能的数组类(头歌实践教学平台习题)【合集】
1. **相关排序和查找算法的原理**:介绍直接插入排序、直接选择排序、冒泡排序和顺序查找的基本原理及其实现代码。 2. **C++ 类与成员函数的定义**:讲解如何定义`Array`类,包括类的声明和实现,以及成员函数的定义与调用。 3. **数组作为类的成员变量的处理**:探讨内存管理和正确访问数组元素的方法,确保在类中正确使用动态分配的数组。 4. **函数参数传递与返回值处理**:解释排序和查找函数的参数传递方式及返回值处理,确保函数功能正确实现。 通过掌握这些知识,可以顺利地将排序和查找算法封装到`Array`类中,并进行测试验证。编程要求是在右侧编辑器补充代码以实现三种排序算法
29 5

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等