首页 > 编程语言 >【C++】string类(上)

【C++】string类(上)

时间:2024-07-24 10:55:13浏览次数:16  
标签:返回 字符 string C++ 字符串 拷贝 字节

在这里插入图片描述

个人主页~


string

一、标准库中的string类

1、什么是string类

(1)字符串是表示字符序列的类,string是表示字符串的字符串类
(2)标准的字符串提供了对此类对象的支持,其接口类似于标准字符容器的接口与常规容器的接口基本相同,但添加了专门用于操作单字节字符字符串的设计特性,也就是专门用来操作string的常规操作
(3)string类是使用char作为它的字符类型
(4)string类是basic_string模版类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数
在这里插入图片描述

basic_string<char> s1;
string s2;
//这两个是一样的,string就是basic_string的char类型特化
typedef basic_string<char, char_traits, allocator> string;//底层

(5)不能操作多字节或者变长字符的序列
(6)在使用时要包头文件以及展开命名空间

2、string类的常用接口讲解

(1)string类的常见构造

函数名称功能说明
string()构造空的字符串
string(const char* s)用C格式的字符串构造字符串
string(const string& s)拷贝构造函数
string(size_t n,char c)字符串中包含n个字符c
void test()
{
	string s1;
	string s2("hello world");
	string s3(s2);
	string s4(5, 'a');
}

在这里插入图片描述

(2)string类的容量操作

函数名称功能说明
size返回字符串有效字符长度
empty检测字符串是否为空,是返回true,否返回false
clear清空有效字符
reserve为字符串预留空间
resize将有效字符个数改为n个,多出的空间用字符c填充
capacity总空间大小
length返回字符串有效字符长度
void test2()
{
	string s1("hello world");

	cout << s1 << endl;
	//测试size和length
	cout << s1.size() << endl;
	cout << s1.length() << endl;
	//size和length底层实现原理完全相同,在刚刚创造出string的时候,对于字符串来说,叫length很合适,
	//所以起名为length,但不久后STL产生了,为了与其他的模版比如list,vector等统一,
	//所以加了size,保持接口一致性,一般都用size
	
	//测empty
	cout << s1.empty() << endl;
	
	//测capacity
	cout << s1.capacity() << endl;
	
	//测resize
	s1.resize(5, 'a');
	cout << s1 << endl;
	s1.resize(15, 'a');
	cout << s1 << endl;
	//resize(size_t n)与resize(size_t n,char c)都是将字符串中有效字符个数改到n个,
	//不同的是当字符个数增多时,resize(size_t n)用0来填充多出的元素空间,
	//resize(size_t n,char c)用c字符填充多出的元素空间
	//resize改变元素个数时,如果个数增多,可能会改变底层容量的大小,如果减少则不变
	
	//测reserve
	s1.reserve(15);
	cout << s1.capacity() << endl;
	//为string预留空间,如果reserve的参数小于string的底层空间总大小时,reserve不会改变容量大小
	
	//测clear
	s1.clear();
	cout << s1.capacity() << endl;
	s1 += "little monster";//+=在后边有讲解
	cout << s1 << endl;
	//clear只是将string中有效字符清空,不改变底层大小,可以再键入新内容
}

在这里插入图片描述

(3)string类对象的访问及遍历

函数名称功能说明
operator[ ]返回pos位置的字符,const string类调用
begin 和 endbegin获取一个字符的迭代器,end获取最后一个字符的后一个位置的迭代器
rbegin 和 rendrbegin获取一个字符的迭代器,rend获取最后一个字符的后一个位置的迭代器
范围for更简洁的遍历
void test3()
{
	string s1("hello world");

	cout << s1[6] << endl;
	//使用下标操作符[]可以直接找到对应位置的字符
	
	//string::iterator it = s1.begin();
	auto it = s1.begin();//这里体现出了auto的优越性,上面一长串的类型可以直接用auto推导代替
	for (it; it != s1.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
//begin记录第一个有效字符的位置,end记录最后一个有效字符的后一个位置
//从头到尾的打印,++是一个重载运算符,在其他类中,包括链表类也可以直接找到下一个成员

	for (auto it : s1)
	{
		cout << it << " ";
	}
	cout << endl;
//使用范围for进行遍历,十分方便

	auto rit = s1.rbegin();
	for (rit; rit != s1.rend(); rit++)
	{
		cout << *rit << " ";
	}
//rbegin和rend是一对与begin和end相反的函数,rbegin记录的是最后一个有效字符的位置,rend记录的是第一个有效字符的前一个位置,通过++实现逆向输出
}

在这里插入图片描述

(4)string类对象的修改

函数名称功能说明
operator+=在字符串后追加字符串
c_str返回C格式字符串
find从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
push_back在字符串后尾插字符
append在字符串后追加一个字符串
rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr在str中从pos位置开始,截取n个字符,然后将其返回
void test4()
{
	string s1("hello world");
	
	//+=测试
	s1 += "!!!!";
	cout << s1 << endl;
	
	//c_str测试
	cout <<s1.c_str() << endl;
	//c_str就是将c++的格式转化为c语言的格式,这样字符串就可以用C语言的方式来操作
	//并且c_str返回的是指针,因为<<是重载运算符,所以才显示指向的内容
	
	//find测试
	cout << s1.find('w',2) << endl;
	
	//pushback测试
	s1.push_back('6');
	cout << s1 << endl;
	
	//append测试
	s1.append("789");
	cout << s1 << endl;
	
	//rfind测试
	cout << s1.rfind('l' , 6) << endl;
	
	//substr测试
	cout << s1.substr(0, 11) << endl;
	//substr只会截取并返回,不改变s1的内容
}

在这里插入图片描述
在string尾部追加字符时,可以使用push_back , append , += ,push_back只能追加字符,append追加字符串,所以我们一般常用的是+=,既可以追加字符又可以追加字符串,并且使用起来书写简单,代码可读性高

对string进行操作时,如果可预见可以放多少字符,可以用reserve把空间预留好

这里的 find 和 rfind 与 begin rbegin 那一套一样,r都表示相反,注意这里find是从pos开始往后找到的第一个指定字符,rfind是从pos开始往前找到的第一个指定字符,然后返回该字符所在位置的下标

(5)string类非成员函数

函数名称功能说明
operator>>输入运算符重载
operator<<输出运算符重载
getline获取一行字符串
relational operators大小比较
operator+少用,传值返回,深拷贝效率低

这部分内容比较简单,我设置了超链接,直接点进去看一下文档就可以了

(6)其他

string类还有很多其他的操作,不一一列举了,需要时直接打开cplusplus查找文档即可
string类
在这里插入图片描述
在这里插入图片描述

(7)vs和g++下string结构说明

前提:32位平台

vs下的string结构

string总共占28个字节,内部结构稍微复杂一点,有一个联合体,用来定义string中字符串的存储空间:当字符串长度小于16时,使用内部固定的字符数组存放,当字符串长度大于等于16时,从堆上开辟空间,这样保证了字符串在较小时不需要通过堆创建,提高了效率,占16字节

还有一个size_t字段保存字符串长度,占4字节,一个size_t字段保存从堆上开辟空间总的容量,占4字节

最后还有一个指针,4字节,共28字节

g++下string结构

在g++下,string通过写时拷贝实现,只占4个字节,内部只包含一个指针,指向一块堆空间,堆空间内部包含了空间总大小、字符串有效长度、引用计数

写时拷贝:在数据第一次写入到某个存储位置时,首先将原有内容拷贝出来,写到另一位置处,然后再将数据写入到存储设备中,该技术只拷贝在拷贝初始化开始之后修改过的数据
简单来说就是在用之前不开空间,在真正要修改和写入时才开辟空间,可以减少空间的浪费,它是在浅拷贝的基础上增加了引用计数的方式实现的

引用计数:用来记录资源使用者的个数,在构造时,将资源的计数给成1,每增加一个对象使用该资源,就给计数增加1,当某个对象被销毁时,先给该计数减1,然后再检查是否需要释放资源,如果计数为1,说明该对象是该资源的最后一个使用者,将该资源释放,否则因为其他对象还在使用该资源,该资源就不能释放


今日分享就到这里~

在这里插入图片描述

标签:返回,字符,string,C++,字符串,拷贝,字节
From: https://blog.csdn.net/s_little_monster/article/details/140476400

相关文章

  • c++_爆刷n题
    P1089[NOIP2004提高组]津津的储蓄计划题目描述津津的零花钱一直都是自己管理。每个月的月初妈妈给津津300300元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同。为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里,到了年末她会加上20%20%......
  • C++ 运算符重载的注意事项
    C++的运算符重载是一种强大的特性,它允许开发者为已存在的运算符赋予新的含义,以适应特定数据类型的需求。在使用运算符重载时,需要注意以下几点:不改变运算符原有语义:运算符重载应保持运算符原有的基本含义,避免引起混淆。例如,重载加法运算符+时,应确保其结果与常规加法操作相符。......
  • C++进阶 继承
    目录继承的概念及定义继承概念继承定义定义格式 继承关系和访问限定符 继承基类成员访问方式的变化基类和派生类对象赋值转换继承中的作用域派生类的默认成员函数构造函数 拷贝构造函数 赋值运算符重载析构函数总结继承与友元继承与静态成员浅谈复杂的菱......
  • 通讯录管理系统(C++基础知识实现)
    通讯录管理系统描述:本人C++小白一枚,正在学习C++基础知识,给大家分享一款使用C++基础知识实现的通讯录管理系统,一起努力进步,大佬轻点喷。1.知识点(1)预处理器指令(#include,#define);(2)命名空间使用(usingnamespacestd;);(3)函数定义:定义了多个函数,如menu,addContact,show......
  • 【C++】模版初阶
    模版一.泛型编程二.函数模版1.函数模版的概念2.函数模板的格式3.函数模版的原理4.函数模版的实例化5.模板参数的匹配原则三.类模版1.类模板的定义格式2.类模板的实例化一.泛型编程当我们要交换两个变量时,可以使用函数重载,如下:voidSwap(int&x,int&y){}voidS......
  • C++之迭代器
    1.什么是迭代器?2.如何使用迭代器3.C++迭代器说明4.迭代器的高级应用4.1.Enumerator.hpp4.2.Iterator.cpp4.3.输出结果4.4.更多详细代码1.什么是迭代器?迭代器(Iterator)是按照一定的顺序对一个或多个容器中的元素从前往遍历的一种机制,比如for循环就是一种最......
  • C++学习之路——第二天(指针和引用)
    指针和二维数组概述:不管是几维数组,当你使用数组名a而没有取地址操作符&时,它(a)都会退化为指向其第一层的指针。(一维数组指向首元素的指针,二维数组是第一行数组的指针,三维数组是指向其第一层(也就是第一个二维数组)的指针)1、错误示范inta[3][4]={{1,2,3,4},{5,6,7,8},{9......
  • Leetcode之string
    目录前言1.字符串相加2.仅仅反转字母3.字符串中的第一个唯一字符4.字符串最后一个单词的长度5.验证回文串6.反转字符串Ⅱ7.反转字符串的单词Ⅲ8.字符串相乘9.打印日期前言本篇整理了一些关于string类题目的练习,希望能够学以巩固.博客主页:酷酷学!!!点......
  • C++_模板(初阶)
    C++_模板(初阶)泛型编程如何实现一个通用的交换函数呢?voidSwap(int&left,int&right){inttemp=left;left=right;right=temp;}voidSwap(double&left,double&right){doubletemp=left;left=right;right=temp;}v......
  • 【Qt项目制作普通计算器】C++语言
    目录一、概述二、界面设计三、程序代码1、程序代码存放位置2、widget.h文件3、widget.cpp4、main.cpp5、.pro文件6、资源文件的添加一、概述1.规划与设计功能确定:决定计算器将支持哪些基本运算(加、减、乘、除、百分之、平方、开根号、变分数等)。界面设计:设计用......