【C++】C++标准模板库STL (一) string类的使用详解(1)

简介: 【C++】C++标准模板库STL (一) string类的使用详解

一、STL的基础介绍

1. 什么是STL

STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架

2. 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想要阅读部分源代码,可以主要参考这个版本。

3. STL的六大组件

二、string类的介绍

string类是STL中的容器,也是我们学习STL的开始。

1. 为什么学习string类

  • C语言中的字符串
    C语言中基本类型有char类型没有字符串类型,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数(如:strlen, strcmp,strcat,strcpy 等),但是这些库函数与字符串是分离开的,不太符合OOP(面向对象)的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。

因此为了更加高效的使用和管理字符串,C++提出了string类的概念,关于string类的学习我们先学习string类的使用,后面我们进一步深入时我们再去动手模拟实现string类,在这里我们首先知道string类的底层其实就是char类型的顺序表就行了。

2. 标准库中的string类

string类的文档介绍

从文档中我们能看到:

  1. string类basic_string模板类的一个实例,它使用char来实例化basic_string模板类。
  2. string在底层实际是:basic_string模板类的别名,typedef basic_string<char>string;
  3. 不能操作多字节或者变长字符的序列。(如英文使用ASCII编码使用一个字节表示一个字母,汉字如果采用GBK编码占用两个字节表示一个汉字)
  4. 处理多字节或者变长字符的序列要用到以下三个类:
  5. 在使用string类时,必须包含 #include<string>以及using namespace std;

三、string类的常用接口说明

在上面的string类的文档介绍中我们可以看到string类接近有140个不同的接口函数,在这么多的成员函数中,很多都是冗余不必要的,因此下面我只讲解最常用的接口。

在讲解这些函数接口之前,我们先来介绍nposnposstring类里面的一个静态成员变量,因此用string类创建的所有对象访问的都是同一个npos,其次我们来看pos的定义:

首先npos的值是被const修饰了,其值不能更改,然后size_t是无符号整形unsignedtypedef,定义将-1的值赋值给了npos,但npos是无符号整形,因此此时nops的值就是无符号整形的最大值65535。

1. string类对象的常见构造函数

  1. 缺省构造函数,用空字符串初始化string对象
  2. 拷贝构造函数,用string类的对象另一个对象
  3. string类的对象中的字符串的子串初始化一个对象,子串的起始位置是pos,结束位置是pos向后的len个字符,如果len没有给缺省值,默认为npos即从pos位置后面有多少拿多少。
  4. 用C风格的字符串初始化string类的对象
  5. 用C风格的字符串前n个字符初始化string类的对象
  6. 用n个字符初始化string类的对象
#include<iostream>
#include<string>
using namespace std;
int main()
{
  string s0("hello world!");
  string s1;          //default (1)   缺省构造函数   
                //用空字符串初始化s1对象  
  string s2(s0);        //copy (2)      拷贝构造函数   
                //用string类的对象s0初始化s2对象
  string s3(s0, 6, 5);    //substring (3)   用string类的对象s0的字符串的子串"world"初始化s3  
                //这里pos参数表示位置,len表示的是个数
  string s4("hello string");  //from c-string (4) 
                //C风格的字符串初始化string类的对象s4
  string s5("hello world",5); //from sequence(5)  
                //用C风格的字符串前五个字符"hello"初始化string类的对象s5
  string s6(5, 'x');      //fill (6)  
                //用5个'x'初始化string类的对象s6
  cout << s0 << endl;
  cout << s1 << endl;
  cout << s2 << endl;
  cout << s3 << endl;
  cout << s4 << endl;
  cout << s5 << endl;
  cout << s6 << endl;
}


2. string类对象的容量操作

  • 我们先来看看不涉及扩容的函数
#include<iostream>
#include<string>
using namespace std;
int main()
{
  string s1("hello world");
  cout << s1.size() << endl;
  cout << s1.length() << endl;
  cout << s1.capacity() << endl;
  cout << s1.max_size() << endl;
  s1.clear();
  cout << s1.empty() << endl;
  return 0;
}

  • 我们再来看看涉及扩容的函数
  1. std::string::reserve()函数与std::string::shrink_to_fit()函数
//std::string::reserve()函数
#include<iostream>
#include<string>
using namespace std;
int main()
{
  string s1("hello world");
  cout << s1.size() << endl;
  cout << s1.capacity() << endl;
  s1.reserve(200);  //提前把空间扩容到200字节,但不初始化
            //由于string类内部的一些原因(如:对齐等原因),虽然向系统申请的的200字节,
            //但不一定就是200字节,总之系统申请的空间会 >= 你给的指定值
  cout << s1.size() << endl;
  cout << s1.capacity() << endl;
  s1.shrink_to_fit(); //缩减容量让 size == capacity
  cout << s1.size() << endl;
  cout << s1.capacity() << endl;
  return 0;
}

观察会发现,经过reserve()函数的处理后size(字符个数)没有变,但是capacity(容量)改变了。

经过shrink_to_fit()函数处理后size(字符个数)没有变,但是capacity(容量)改变了。(虽然,shrink_to_fit()函数能够减少空间的浪费,但是我们还是一般不缩容,因为缩容的消耗是很大的)

相关文章
|
5月前
|
API C++ Windows
Visual C++运行库、.NET Framework和DirectX运行库的作用及常见问题解决方案,涵盖MSVCP140.dll丢失、0xc000007b错误等典型故障的修复方法
本文介绍Visual C++运行库、.NET Framework和DirectX运行库的作用及常见问题解决方案,涵盖MSVCP140.dll丢失、0xc000007b错误等典型故障的修复方法,提供官方下载链接与系统修复工具使用指南。
1185 2
|
5月前
|
缓存 算法 程序员
C++STL底层原理:探秘标准模板库的内部机制
🌟蒋星熠Jaxonic带你深入STL底层:从容器内存管理到红黑树、哈希表,剖析迭代器、算法与分配器核心机制,揭秘C++标准库的高效设计哲学与性能优化实践。
C++STL底层原理:探秘标准模板库的内部机制
|
5月前
|
Ubuntu API C++
C++标准库、Windows API及Ubuntu API的综合应用
总之,C++标准库、Windows API和Ubuntu API的综合应用是一项挑战性较大的任务,需要开发者具备跨平台编程的深入知识和丰富经验。通过合理的架构设计和有效的工具选择,可以在不同的操作系统平台上高效地开发和部署应用程序。
236 11
|
5月前
|
IDE 编译器 开发工具
msvcp100.dll,msvcp120.dll,msvcp140.dll,Microsoft Visual C++ 2015 Redistributable,Visual C++ 运行库安装
MSVC是Windows下C/C++开发核心工具,集成编译器、链接器与调试器,配合Visual Studio使用。其运行时库(如msvcp140.dll)为程序提供基础函数支持,常因缺失导致软件无法运行。通过安装对应版本的Microsoft Visual C++ Redistributable可解决此类问题,广泛应用于桌面软件、游戏及系统级开发。
669 2
|
5月前
|
编解码 Java 开发者
Java String类的关键方法总结
以上总结了Java `String` 类最常见和重要功能性方法。每种操作都对应着日常编程任务,并且理解每种操作如何影响及处理 `Strings` 对于任何使用 Java 的开发者来说都至关重要。
370 5
|
6月前
|
并行计算 C++ Windows
|
9月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
236 0
|
9月前
|
存储 编译器 C语言
关于string的‘\0‘与string,vector构造特点,反迭代器与迭代器类等的讨论
你真的了解string的'\0'么?你知道创建一个string a("abcddddddddddddddddddddddddd", 16);这样的string对象要创建多少个对象么?你知道string与vector进行扩容时进行了怎么的操作么?你知道怎么求Vector 最大 最小值 索引 位置么?
233 0
|
缓存 安全 Java
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
328 11