【C++】string类
一、C++ 标准库中的string类
1、string类
string类的文档介绍
首先string并不是STL中的,而是一个类string比STL出现的早
从上面可以看出string是从一个类模板中实例化出来的一个对象
在使用string类是必须要包头文件#include< string >
又因为是std中的类,所以要using namespace std; 将std开放,否则就要在使用时加上std::
//开放std类域
string s1;
//未开放,需要表明是哪个类域的
std::string s2;
2、auto和范围for
auto关键字
<1>
在早期C/C++中auto的含义是:使用auto的变量,是具有自动存储器的局部变量,后来不重要了,那为什么不重要了呢?
因为自动存储器的作用是变量的自动开辟自动释放,但是在后面函数结束后栈会自动回收开辟的空间,在C语言中每一个变量都会在变量类型前加上auto
//C
int a = 0;
auto int a = 0;
//C++
//报错:c3530:“auto”不能与任何其他类型说明符组合
auto int a = 0;
那为什么在C++中不可以了呢?因为在C++11中重新拾起了这个已经不重要的关键字,并赋予了新的定义:
auto不在是一个存储类型的指示符,而作为一个新的类型指示符来指示编译器,auto指示的变量的数据类型必须由编译阶段推到而来
#include<iostream>
using namespace std;int main()
{int a = 10;auto b = a;auto c = 1.1;//typeid().name() 可以显示数据类型cout << typeid(a).name() << endl;cout << typeid(b).name() << endl;cout << typeid(c).name() << endl;//报错:c3531:“e”: 类型包含“auto”的符号必须具有初始值设定项//auto e;return 0;
}
由上面的图可以看出:
1、string是std中的类
2、string是模板的实例化
<2>
auto在声明指针类型变量时,auto 和 auto* 没有区别,但在auto声明引用变量时必须要加上&
#include<iostream>
using namespace std;int main()
{//指针int a = 0;auto b = &a;auto* c = &a;cout << typeid(b).name() << endl;cout << typeid(c).name() << endl;//引用auto& d = a;d = 10;cout << a << endl;return 0;
}
<3>
当在同一行声明多个变量时,变量的数据类型必须相同,否则编译器会报错,因为auto会对第一个变量进行推导,以此推导结果来定义剩下的变量
auto a = 1, b = 2;//错误 C3538 在声明符列表中,“auto”必须始终推导为同一类型
auto c = 1, d = 1.1;
<4>
auto不能作为函数的参数,但是可以做函数的返回值,但请谨慎使用,因为在函数多层嵌套时使用auto做返回值会使代码可读性下降
//auto做函数参数
//报错:c3533:参数不能为包含“auto”的类型
int func1(auto a)
{return a;
}//auto做函数返回值
auto func2()
{int a = 0;return a;
}
<5>
auto不能声明数组
//报错:c3318: “auto []”: 数组不能具有其中包含“auto”的元素类型
auto array[] = { 1,2,3,4 };
范围for
<1>
对于一个有范围的集合而言,由程序员来说明循环的范围有些多余,而且还容易范错误,所以在C++11之后引入了基于范围的for循环:
for循环中由 “:” 分为两部分,第一部分用来表示被迭代的变量,第二部分用来表示被迭代的范围。
自动迭代,自动取数据,自动判断结束
<2>
范围for可以作用到数组和容器上进行遍历
#include<iostream>
#include <string>
using namespace std;
int main()
{int array[] = { 1, 2, 3, 4, 5 };// C++98的遍历for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i){array[i] *= 2;}for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i){cout << array[i] << endl;}// C++11的遍历for (auto& e : array)e *= 2;for (auto e : array)cout << e << " " << endl;string str("hello world");for (auto ch : str){cout << ch << " ";}cout << endl;return 0;
}
<3>
范围for底层也很简单,容器遍历实际上就是用迭代器进行替换,底层汇编也可以看出
二、string类常用接口
只是常用的,其他的只做了解,在需要时能想起来有,并且能查就行,并且下面的都只是C++98版本的,C++11以及往后新加的并没有涉及
1、string类的常见构造(constructor)
constructor(构造)----------链接
constructor函数名称(重点掌握) | 功能说明 |
---|---|
string( ) | 构造空string类对象,即空字符串 |
string (const char* s) | 用C-string来构造string类对象 |
string (size_t n, char c) | string对象中包含 n 个字符 c |
string (const string& str) | 拷贝构造函数 |
#include<iostream>
#include<string>
using namespace std;int main()
{//default (1) string();string s1;cout << "s1 : " << s1 << endl;//from C-string (4) string(const char* s)string s2("123456");cout << "s2 : " << s2 << endl;//copy (2) string(const string & str)string s3(s2);cout << "s3 : " << s3 << endl;//substring (3) string(const string & str, size_t pos, size_t len = npos)string s4(s2, 2, 3);cout << "s4 : " << s4 << endl;//因为此函数不管后面的len填多少到字符串末尾就会结束//上面函数参数 size_t len有缺省值npos,就是如果不填会默认填最大值string s5(s2, 1);cout << "s5 : " << s5 << endl;//from sequence (5) string(const char* s, size_t n)string s6("1111111", 4);cout << "s6 : " << s6 << endl;//fill (6) string(size_t n, char c)string s7(7, 'c');cout << "s7 : " << s7 << endl;return 0;
}
2、string 类对象的容量操作
3、string类对象的访问及遍历操作
函数名称 | 功能说明 |
---|---|
operator[ ] | 返回pos位置的字符,const string类对象调用 |
– | – |
<1>operator[ ]
#include<iostream>
#include<string>
using namespace std;int main()
{string s1("1234567");cout << s1 << endl;s1[2] = '4';cout << s1 << endl;const string s2("111111111");cout << s2[2] << endl;return 0;
}