当前位置: 首页 > news >正文

专线网站建设百度里面的站长工具怎么取消

专线网站建设,百度里面的站长工具怎么取消,设计师接单平台知乎,wordpress 端口 跳转目录 六、STL简介 (一)什么是STL (二)STL的版本 (三)STL六大组件 七、string (一)标准库中的string 1、string类 2、string常用的接口 1)string类对象的常见构造 2)string类对象的容量操作 3)string类对象的访问及遍历操作 4)string类对象的修改操作 5)string类非成…

 

目录

六、STL简介

(一)什么是STL

(二)STL的版本

(三)STL六大组件

七、string

(一)标准库中的string

 1、string类

2、string常用的接口 

1)string类对象的常见构造

 2)string类对象的容量操作

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

4)string类对象的修改操作

5)string类非成员函数

(二)string模拟实现

 1、浅拷贝

2、深拷贝

3、实现 


六、STL简介

(一)什么是STL

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

(二)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 要阅读部分源代码, 主要参考的就是这个版本。

(三)STL六大组件

 学习STL的三个境界:能用,明理,能扩展

七、string

string严格来说不是STL,而是标准库。

(一)标准库中的string

 1、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) 的序列,这个
类的所有成员 ( 如长度或大小 ) 以及它的迭代器,将仍然按照字节 ( 而不是实际编码的字符 ) 来操作。

2、string常用的接口 

1)string类对象的常见构造

以下是常用的构造方式

    string s1;string s2("123");string s3 = "123";string s4(s3);
 2)string类对象的容量操作
函数名称作用
size返回字符串有效长度
length返回字符串有效长度
capacity返回空间总大小
empty若字符串为空返回true,不为空返回false
clear清空有效字符
reserve预留空间
resize将字符串大小改为n
#include<string>
int main()
{string s = "C++";cout << s << endl;cout <<"s.size():"<< s.size() << endl;cout <<"s.length():"<< s.length() << endl;cout << "s.capacity():"<<s.capacity() << endl;cout << "s.empty():"<<s.empty() << endl;cout << "-----------------------------------------------------" << endl;s.resize(6);cout << "s.size():" << s.size() << endl;cout << "s.capacity():" << s.capacity() << endl;cout << "-----------------------------------------------------" << endl;s.reserve(16);cout << "s.capacity():" << s.capacity() << endl;cout << "-----------------------------------------------------" << endl;s.clear();cout << "s.empty():" << s.empty() << endl;return 0;
}

string 容量相关方法使用代码演示
注意:
1. size() length() 方法底层实现原理完全相同,引入 size()的原因是为了与其他容器的接口保持一
致,一般情况下基本都是用 size()
2. clear() 只是将 string 中有效字符清空,不改变底层空间大小。
3. resize(size_t n) resize(size_t n, char c) 都是将字符串中有效字符个数改变到 n 个,不同的是当字符个数增多时:resize(n) 0 来填充多出的元素空间, resize(size_t n, char c) 用字符 c 来填充多出的元素空间。注意:resize 在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大
小,如果是将元素个数减少,底层空间总大小不变。
4. reserve(size_t res_arg=0) :为 string 预留空间,不改变有效元素个数,当 reserve 的参数小于
string 的底层空间总大小时, reserver不会改变容量大小
3)string类对象的访问及遍历操作
函数名称作用
operator[]
返回 pos 位置的字符, const string 类对象调用
begin+end返回首元素地址+返回最后一个元素的下一个位置的地址
rbegin+rend返回最后一个元素的地址+返回第一个元素的前一个位置地址
范围forfor的新遍历方式(C++11)
    string s = "asdfghjkl";string::iterator it = s.begin();while (it != s.end()){cout << *it ;it++;}cout << endl;

这就是正向迭代器,其中string::iterator也可以用auto

	string s = "asdfghjkl";auto it = s.begin();while (it != s.end()){cout << *it ;it++;}cout << endl;

 还有反向迭代器

	string s = "asdfghjkl";auto it = s.rbegin();while (it != s.rend()){cout << *it ;it++;}cout << endl;

范围for(原理:编译器会将范围for变成迭代器)

	string s = "asdfghjkl";for (auto a : s){cout << a;}cout << endl;
4)string类对象的修改操作
函数名称作用
push_back在字符串尾部添加字符
append在字符串后面追加一个字符串
operator+=在字符串后面追加字符串str
c_str返回C格式的字符串
find+npos
从字符串pos位置开始往后找字符,返回该字符在字符串中的位置
rfind
从字符串pos位置开始往前找字符,返回该字符在字符串中的位置
substr
在str中从pos位置开始,截取n个字符,然后将其返回
insert插入字符或字符串
erase删除字符或字符串
int main()
{string s = "hello ";cout << s << endl;cout << "------------------------------------------------" << endl;s.push_back('w');cout << s << endl;cout << "------------------------------------------------" << endl;s += "orld";cout << s << endl;cout << "------------------------------------------------" << endl;s.append(" /C++");cout << s << endl;cout << "------------------------------------------------" << endl;cout << s.find('h') << endl;cout << "------------------------------------------------" << endl;cout << s.substr(2, 5) << endl;cout << "------------------------------------------------" << endl;s.insert(0,1,'+');s.insert(s.begin(), '+');cout << s << endl;cout << "------------------------------------------------" << endl;s.erase(0, 2);cout << s << endl;cout << "------------------------------------------------" << endl;return 0;
}

注意,我们在文档时,substr是有缺省值的

 当我们不给截多少字符的时候,会给npos值,那么npos值是多少呢???

是-1吗???

文档中npos的类型是size_t,这是无符号整形,也就是说这里的-1并不真的是,而是42亿+

到现在为止,我们并没有遇到过这么大的长度,所以可以理解为,截到字符串结束

还有值得注意的是insert

在插入一个字符的时候我们需要传三个参数,或者传迭代器也就是(6)

	s.insert(0,1,'+');            //(5)s.insert(s.begin(), '+');     //(6)

当erasr没有第二个参数时,默认为删除到字符串最后

5)string类非成员函数
函数名称作用
operator+字符串添加,不改变原来的字符串
operator>>输入运算符重载
operator<<输出运算符重载
getline获取一行字符串
relational operators比较大小
#include<string>
int main()
{string s = "hello ";cout << s << endl;cout << "------------------------------------------------" << endl;string s2 = s + "C++";cout << s << endl;cout << s2 << endl;cout << "------------------------------------------------" << endl;string s4;getline(cin, s4);cout << s4 << endl;cout << "------------------------------------------------" << endl;return 0;
}

getline主要是解决cin遇到空格就停止读取的问题

这些是比较常见的string接口,当然还有很多接口

具体介绍,大家可以看看官网 icon-default.png?t=N7T8https://cplusplus.com/

(二)string模拟实现

 1、浅拷贝

下面代码是有问题的 

class String
{
public:
/*String():_str(new char[1]){*_str = '\0';}*///String(const char* str = "\0") 错误示范//String(const char* str = nullptr) 错误示范String(const char* str = ""){// 构造String类对象时,如果传递nullptr指针,可以认为程序非if (nullptr == str){assert(false);return;}_str = new char[strlen(str) + 1];strcpy(_str, str);}~String(){if (_str){delete[] _str;_str = nullptr;}}
private:char* _str;
};
// 测试
void TestString()
{String s1("hello bit!!!");String s2(s1);
}

说明:上述 String 类没有显式定义其拷贝构造函数与赋值运算符重载,此时编译器会合成默认的,当用 s1 s2 时,编译器会调用默认的拷贝构造。最终导致的问题是, s1 s2 共用同一块内存空间,在释放时同一块 空间被释放多次而引起程序崩溃 ,这种拷贝方式,称为浅拷贝。
浅拷贝:也称位拷贝,编译器只是将对象中的值拷贝过来 。如果 对象中管理资源 ,最后就会 导致多个对象共 享同一份资源,当一个对象销毁时就会将该资源释放掉,而此时另一些对象不知道该资源已经被释放,以为 还有效,所以当继续对资源进项操作时,就会发生发生了访问违规
可以采用深拷贝解决浅拷贝问题,即: 每个对象都有一份独立的资源,不要和其他对象共享

2、深拷贝

如果一个类中涉及到资源的管理,其拷贝构造函数、赋值运算符重载以及析构函数必须要显式给出。一般情况都是按照深拷贝方式提供。

3、实现 

代码仅供参考 

class string
{friend ostream& operator<<(ostream& out, const string& s);friend istream& operator>>(istream& in, string& s);
public:typedef char* iterator;string(const char* str = ""):_size(strlen(str)),_capacity(_size){_str = new char[_capacity + 1];strcpy(_str, str);}string(const string& s){char* tmp = new char[_capacity + 1];strcpy(tmp, s._str);_str = tmp;_size = s._size;_capacity = s._capacity;}~string(){delete[] _str;_str = nullptr;_size = _capacity = 0;}iterator begin(){return _str;}iterator end(){return _str + _size;}const iterator begin()const{return _str;}const iterator end()const{return _str + _size;}void reserve(size_t n){if(n>_capacity){char* tmp = new char[n+1];strcpy(tmp,_str);delete[] _str;_str = tmp;_capacity = n;}}void push_back(char c){if (_size == _capacity){reserve(_capacity == 0 ? 4 : _capacity * 2);}_str[_size] = c;_size++;_str[_size] = '\0';}string& operator+=(char c){push_back(c);return *this;}void append(const char* str){size_t len = strlen(str);if (_size + len > _capacity){reserve( _size + len );}strcpy(_str + _size, str);_size += len;}string& operator+=(const char* str){append(str);return *this;}void clear(){_str[0] = '\0';_size =  0;}void swap(string& s){std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}string substr(size_t pos,size_t len = npos){string s;int a = pos;if (len == npos || len >= _size){len = _size - pos;s.reserve(len);for (int i = pos; i < _size; i++){s += _str[i];}}else{s.reserve(len);for (int i = pos; i < pos + len; i++){s += _str[i];}}return s;}string& insert(size_t pos,size_t len,char c){assert(pos <= _size);if (_size + len > _capacity){reserve(_size + len);}int a = _size;while (a >= (int)pos){_str[a + len] = _str[a];a--;}int i = pos;while (i < pos+len){_str[i] = c;i++;}_size++;return *this;}string& insert(size_t pos, const char* str){int len = strlen(str);assert(pos <= _size);if (_size + len > _capacity){reserve(_size + len);}int a = _size;while (a >= (int)pos){_str[a + len] = _str[a];a--;}int i = pos;int j = 0;while (i < pos + len){_str[i] = str[j];i++;j++;}_size += len;return *this;}size_t size()const{return _size;}size_t capacity()const{return _capacity;}const char*c_str()const{return _str;}bool empty()const{return _size == 0;}void resize(size_t n, char c = '\0'){if (n < _size){_str[n] = '\0';_size = n;}if (n > _size){reserve(n);while (_size < n){_str[_size] = c;_size++;}_str[_size] = '\0';}}char operator[](size_t index){assert(index < _size);return _str[index];}const char& operator[](size_t index)const{assert(index < _size);return _str[index];}bool operator<(const string& s){int num1 = 0;int count = 0;while (num1<_size && num1 < s._size){if (_str[num1] > s._str[num1])return false;if (_str[num1] < s._str[num1])count++;num1++;}if (s._str[num1] != '\0')return true;if (count == 0)return false;return true;}bool operator==(const string& s){int num1 = 0;while (num1 < _size && num1 < s._size){if (_str[num1] != s._str[num1]){return false;}num1++;}if (s._str[num1] != '\0'||_str[num1]!='\0')return false;return true;}bool operator<=(const string& s){return *this == s || *this < s;}bool operator>(const string& s){return !(*this <= s);}bool operator>=(const string& s){return *this == s || *this > s;}bool operator!=(const string& s){return !(*this== s);}// 返回c在string中第一次出现的位置size_t find(char c, size_t pos = 0) const{int a = pos;while (a < _size){if (_str[a] == c)return a;a++;}return -1;}// 返回子串s在string中第一次出现的位置size_t find(const char* s, size_t pos = 0) const{int a = pos;int i = 0;while (a < _size){int j = a;while (_str[j] == s[i]){i++;j++;if (s[i] == '\0')return a;}i = 0;a++;}}// 删除pos位置上的元素string& erase(size_t pos, size_t len){if (len >= _size){_str[pos] = '\0';_size = pos;return *this;}int a =  pos;while (a+len <= _size){_str[a] = _str[a + len];a++;}_size -= len;return *this;}const static size_t npos;
private:char* _str;size_t _size;size_t _capacity;
};
const size_t string::npos = -1;
ostream& operator<<(ostream& out, const string& s)
{for (auto a : s){cout << a;}return cout;
}
istream& operator>>(istream& in, string& s)
{s.clear();char ch;ch = in.get();while (ch!='\n'){s += ch;ch = in.get();}return in;
}

http://www.hengruixuexiao.com/news/33993.html

相关文章:

  • 网站后台上传文章格式百度竞价推广什么意思
  • 施工企业破产质保seo搜索引擎优化营销案例
  • 企业网站备案建设方案策划书排名优化公司口碑哪家好
  • 长沙专业网站优化定制宣传软文怎么写
  • 建设项目银行网站企业网站建设方案论文
  • 包头做网站公司广告资源网
  • 中文html5网站欣赏宁波seo优化项目
  • 做竞价的网站如何做企业网站
  • 模板网站哪家好网站策划方案书
  • 网站建设需要哪些技术人员简述常用的网络营销方法
  • 个人网站建设基础与实例2020十大网络热词
  • 嘉兴手机网站制作360网站推广费用
  • 长沙仿站模板网站建设网络推广渠道分类
  • 做移动网站优化排名十大互联网平台
  • 网站如何做关键词seo腾讯广告推广平台
  • 网站初期做几个比较好娄底地seo
  • 巴中网站建设seo sem关键词优化
  • 博客网站开发搜索引擎seo是什么
  • 网站 手机版 电脑版 怎么做下载百度2023最新版安装
  • wordpress网站下载文件长尾关键词挖掘精灵官网
  • 辽宁网站建设百度的营销中心上班怎么样
  • 用rp怎么做网站按钮下拉框简述搜索引擎的工作原理
  • 南宁seo建站域名停靠网页推广大全
  • 怎么注册域名免费谷歌seo软件
  • 南宁网站推广公司如何在百度推广
  • 微信小程序开发报价优化seo方案
  • 宝塔做网站安全吗技术培训班
  • 网站每天一条推送怎么做的江门关键词优化公司
  • 正规的饰品行业网站开发百度前三推广
  • 汽车网站建设方案刷赞网站推广空间免费