C++:string类(第一章)

server/2024/10/18 8:25:38/

hello,各位小伙伴,本篇文章跟大家一起学习《C++:string类》,感谢大家对我上一篇的支持,如有什么问题,还请多多指教 !
如果本篇文章对你有帮助,还请各位点点赞!!!
在这里插入图片描述

话不多说,开始进入正题

文章目录

  • :rocket:什么是string类
  • :rocket:string类对象的构造
    • 1.:airplane:无参构造
    • 2.:airplane:拷贝构造函数
    • 3.:airplane:用C-string来构造string类对象
    • 4.:airplane:子字符串构造函数
  • :rocket:string类对象的访问及遍历操作
    • :airplane:1.string类的迭代器`iterator`
    • :airplane:2.operator[]
    • :airplane:3.begin + end
      • :fire:begin
      • :fire:end
    • :airplane:4.rbegin + rend
      • :fire:rbegin
      • :fire:rend
      • :fire:rbegin + rend结合使用如下:
    • :airplane:5.范围for
  • :rocket:string类对象的容量操作
    • :airplane:1.size
    • :airplane:2.capacity
    • :airplane:3.empty
    • :airplane:4.clear

🚀什么是string类

C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。
OOP是面向对象编程的意思

所以,C++引入了string类

  1. 字符串是表示字符序列的类
  2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。
  3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信息,请参阅basic_string)。
  4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。
  5. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。

总结:

  1. string是表示字符串的字符串类
  2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
  3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator>string;
  4. 不能操作多字节或者变长字符的序列。

在使用string类时,必须包含#include头文件以及using namespace std;

🚀string类对象的构造

本文章讲的string类对象的构造只讲比较常用的构造方法以及一些细节。
如下为string类对象的构造:
在这里插入图片描述

1.✈️无参构造

string();

#include<string>
int main()
{string s1;return 0;
}

此构造为string类的默认构造,构造一个无字符的串(空字符串):

Constructs an empty string, with a length of zero characters.

2.✈️拷贝构造函数

string (const string& str);

#include<string>
int main()
{string s1("hello world");string s2(s1);return 0;
}

Constructs a copy of str.

3.✈️用C-string来构造string类对象

string (const char* s);

#include<string>
int main()
{string s1("hello world");char C_s[] = "hello world";string s2(C_s);return 0;
}

当然,还可以这么写:

string s3 = "hello world";

这里有个隐式类型转换的过程,"hello world"会生成一个string类的临时对象,赋值给s3

string s3 = "hello world";
const string& s4 = "hello world";

因为临时对象具有常性,所以s4需要用const修饰。

复制s所指向的以null结尾的字符序列(C字符串):

Copies the null-terminated character sequence (C-string) pointed by s.

简单说就是:用一个已有的字符串来初始化。

4.✈️子字符串构造函数

string (const string& str, size_t pos, size_t len = npos);

#include<iostream>
#include<string>
using namespace std;int main()
{string s1("hello world");string s2(s1, 0, 5);cout << s1 << endl;cout << s2 << endl;return 0;
}

从结果可以猜到,这是string类的部分拷贝初始化:

  1. pos就是拷贝的初始位置(在哪个位置开始拷贝)
  2. len就是拷贝的长度
  3. nposlen的缺省值,其实是-1,由于size_t是无符号整型,也就是42亿左右,那么不难看出,当我们不穿第三个参数(使用len的缺省值),相当于pos位置后面的字符全部拷贝

🚀string类对象的访问及遍历操作

✈️1.string类的迭代器iterator

string 类在 C++ 中提供了多种迭代器类型,包括普通迭代器、常量迭代器、反向迭代器等,可以用来遍历字符串的字符。

  1. 普通迭代器 (iterator):

    • string::iteratorstring 类的普通迭代器,用于修改字符串内容。
    • 例如:
      std::string str = "Hello";
      for (std::string::iterator it = str.begin(); it != str.end(); ++it) {*it = std::toupper(*it); // 将字符转换为大写
      }
      
  2. 常量迭代器 (const_iterator):

    • string::const_iteratorstring 类的常量迭代器,用于遍历字符串但不能修改其中的字符。
    • 例如:
      std::string str = "Hello";
      for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) {std::cout << *it; // 打印字符
      }
      
  3. 反向迭代器 (reverse_iteratorconst_reverse_iterator):

    • string::reverse_iteratorstring::const_reverse_iteratorstring 类的反向迭代器,用于从末尾向前遍历字符串。
    • 例如:
      std::string str = "Hello";
      for (std::string::reverse_iterator rit = str.rbegin(); rit != str.rend(); ++rit) {std::cout << *rit; // 从后向前打印字符
      }
      
    • 要注意的是:rit还是++,不是--!!!

这些迭代器类型可以根据需要选择,可以实现对字符串的遍历和修改操作。

✈️2.operator[]

char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;

返回pos位置的字符,const string类对象调用

我们依然可以像字符串数组一样使用[]来访问串内单个字符,如下:

int main()
{string s1("hello world");for (int i = 0; i < 12; ++i){cout << s1[i] << " ";}return 0;
}

同样,我们也可以对串内单个字符进行修改,如下:

int main()
{string s1("hello world");for (int i = 0; i < 12; ++i){++s1[i];cout << s1[i] << " ";}return 0;
}

小细节:operator[]assert检查是否越界

If pos is equal to the string length and the string is const-qualified, the function returns a reference to a null character (‘\0’)

✈️3.begin + end

🔥begin

iterator begin();
const_iterator begin() const;

Returns an iterator pointing to the first character of the string.

begin获取第一个字符的迭代器,如下:
c

🔥end

iterator end();
const_iterator end() const;

Returns an iterator pointing to the past-the-end character of the string.

end获取最后一个字符下一个位置的迭代器如下:

int main()
{string s1("hello world");string::iterator lt1 = s1.end()-1;cout << *lt1 << endl;return 0;
}

可以与begin一起使用遍历串:

string s1("hello world");
for (string::iterator i = s1.begin(); i < s1.end(); i++)
{cout << *i << " ";
}

也可以用auto修饰i,如下:

string s1("hello world");
for (auto i = s1.begin(); i < s1.end(); i++)
{cout << *i << " ";
}

✈️4.rbegin + rend

🔥rbegin

reverse_iterator rbegin();
const_reverse_iterator rbegin() const;

Returns a reverse iterator pointing to the last character of the string (i.e., its reverse beginning).

返回一个反向迭代器,该迭代器指向字符串的最后一个字符(即其反向开头)

🔥rend

reverse_iterator rend();
const_reverse_iterator rend() const;

Returns a reverse iterator pointing to the theoretical element preceding the first character of the string(which is considered its reverse end).

返回一个反向迭代器,该迭代器指向字符串第一个字符(被视为其反向端)前面的理论元素。

🔥rbegin + rend结合使用如下:

int main()
{string s1("hello world");for (auto i = s1.rbegin(); i < s1.rend(); i++){cout << *i << " ";}return 0;
}

✈️5.范围for

直接看代码:

int main()
{string s1("hello world");for (auto i : s1){cout << i << " ";}return 0;
}

🚀string类对象的容量操作

✈️1.size

size_t size() const;

返回字符串的有效长度,如下:
要注意:size是不计算\0的!!!

int main()
{string s1("hello world");cout << s1.size() << endl;return 0;
}

也有一个作为同样功能的操作,length

int main()
{string s1("hello world");cout << s1.length() << endl;return 0;
}

但是我们更常用size

✈️2.capacity

返回空间总大小,如下:

int main()
{string s1("hello world");cout << s1.capacity() << endl;return 0;
}

不过,有一点需要注意的是:为什么如上代码的输出结果为15呢?

在这段代码中,s1 是一个 string 对象,它使用字符串 “hello world” 进行初始化。在 C++ 的标准库实现中,string 类通常会使用动态内存分配来存储字符串内容。capacity() 方法返回的是当前 string 对象分配的内存空间大小,而不是字符串的实际长度。这是为了避免每次添加字符时都要重新分配内存,提高性能。

对于 “hello world” 这个字符串,实际长度为 11(包括空格),但 string 类一般会预留额外的空间以容纳未来的扩展,以减少频繁的内存分配。因此,当你查询 capacity() 时,得到的值可能会大于字符串的实际长度。在这种情况下,15 表示 string 对象当前分配的内存空间大小,而不是字符串的实际长度。

如图所示:
在这里插入图片描述
可以看到hello world存放于_Buf里,但是,当s1超过15个有效字符时,如下:

int main()
{string s1("hello world xxxxxx");cout << s1.capacity() << endl;return 0;
}

在这里插入图片描述
可以看到hello world xxxxxx存放于Ptr里,其实就是存放在堆上

✈️3.empty

bool empty() const;

Returns whether the string is empty (i.e. whether its length is 0)

检测字符串释放为空串,是返回true,否则返回false,如下:

int main()
{string s1("hello world");cout << s1.empty() << endl;return 0;
}

✈️4.clear

void clear();

Erases the contents of the string, which becomes an empty string (with a length of 0 characters).

擦除字符串的内容,该字符串将变为空字符串(长度为0个字符),如下:

int main()
{string s1("hello world");cout << s1 << endl;s1.clear();cout << s1 << endl;return 0;
}

要注意:clear()只是将string中有效字符清空,不改变底层空间大小。

你学会了吗?
好啦,本章对于《C++:string类(第一章)》的学习就先到这里,如果有什么问题,还请指教指教,希望本篇文章能够对你有所帮助,我们下一篇见!!!

如你喜欢,点点赞就是对我的支持,感谢感谢!!!

请添加图片描述


http://www.ppmy.cn/server/28242.html

相关文章

Django之创建Model以及后台管理

一&#xff0c;创建项目App python manage.py startapp App 二&#xff0c;在App.models.py中创建类&#xff0c;以下是示例 class UserModel(models.Model):uid models.AutoField(primary_keyTrue, auto_createdTrue)name models.CharField(max_length10, uniqueTrue, db…

Linux procinfo命令教程:如何查看和理解系统信息(附案例详解和注意事项)

Linux procinfo命令介绍 procinfo&#xff08;process information&#xff09;是一个简单的命令行工具&#xff0c;用于查看从/proc目录收集的系统信息&#xff0c;并将其美观地格式化输出到标准输出设备。 Linux procinfo命令适用的Linux版本 procinfo命令在大多数Linux发…

JVM对象锁的升级过程

在Java中&#xff0c;锁升级是一个动态过程&#xff0c;JVM根据运行时的线程竞争情况自动调整锁的状态。这个过程涵盖从偏向锁到轻量级锁&#xff0c;最后可能升级到重量级锁。下面详细解释每个步骤以及它们之间的转换机制。 1. 偏向锁 偏向锁是一种针对单线程执行代码块的优…

c#word文档:1.创建空白Word文档及保存/2.添加页内容...

---创建空白Word文档 --- &#xff08;1&#xff09;创建一个名为OfficeOperator的类库项目。引用操作Word的.NET类库 &#xff08;2&#xff09;定义用于操作Word的类WordOperator1。添加引用Microsoft.Office.Interop.Word命名空间。 &#xff08;3&#xff09;为WordOper…

E0266错误(byte重定义),谨慎使用using namespace语句

解决启用C17后byte重定义的问题&#xff08;byte ambiguous &#xff09; 转载于&#xff1a;返回主页松山居士的家 在C 17的cstddef文件中引入了 一种std::byte类型&#xff0c;在部分项目升级时往往会与系统中的byte定义冲突&#xff0c;导致编译失败。 但std::byte类型是…

IOS上线操作

1、拥有苹果开发者账号 2、配置证书&#xff0c;进入苹果开发者官网&#xff08;https://developer.apple.com/&#xff09; 3、点击账户&#xff08;account&#xff09;&#xff0c;然后创建一个唯一的标识符 4、点击"Identifiers"&#xff0c;然后点击"&qu…

向eclipse中的项目导入jdk、tomcat

前言&#xff1a; 有些项目无法正常启动可能是因为他的基础配置不正确或者没配置&#xff0c;eclipse中的javaweb项目常见的配置就是jdk、tomcat&#xff0c;这三者配置的方式大概相同&#xff0c;以下是相关操作。我的环境是eclipse2018。 一、jdk 在项目上右键选中propert…

【C语言】文件操作(万字解读超详细解析)

最好的时光&#xff0c;在路上;最好的生活&#xff0c;在别处。独自上路去看看这个世界&#xff0c;你终将与最好的自己相遇。&#x1f493;&#x1f493;&#x1f493; 目录 • ✨说在前面 &#x1f34b;知识点一&#xff1a;什么是文件&#xff1f; • &#x1f330;1.程序…