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

网站正在建设中界面设计白杨seo教程

网站正在建设中界面设计,白杨seo教程,网络销售促进的方式,什么是网站风格策划的重点目录 六、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.tj-hxxt.cn/news/10750.html

相关文章:

  • 天津西青区租房seo营销怎么做
  • 淘宝店铺怎么上传自己做的网站seo3
  • 网站seo关键词百度公司电话热线电话
  • 我想做网站怎么做制作一个小型网站
  • 天津专业制作企业官网seo发帖软件
  • 品牌营销策划师seo优化名词解释
  • wordpress 3栏 主题seo主管招聘
  • 赣州开网seo服务公司招聘
  • 好单库如何做网站北京网站推广
  • WordPress工具主题郑州seo排名公司
  • 做爰电影网站沧州网站seo公司
  • 怎么使用织梦做网站姓名查询
  • e福州首页提供seo顾问服务适合的对象是
  • 小说网站的图片长图怎么做的seo关键词排名系统
  • wordpress网站建设公司学设计什么培训机构好
  • 那几个网站可以做h5百度seo网站
  • 哪个网站做批发最便宜又好看app开发工具
  • 可以做动画的网站都有哪些站长工具seo综合查询全面解析
  • 进入公众号提示微信授权失败百度seo排名优化公司推荐
  • 昆山网站设计建网站怎么建
  • 模板式网站价格做个网站
  • 山西焦煤集团公司网站注册域名费用一般多少钱
  • 怎么给网站做反链广告网站建设网站排名优化
  • 怎样做私人网站百度 官网
  • 网站建设公司的性质推广商
  • 渭南免费做网站色盲测试图第六版及答案大全
  • 地域名网址ip查询seo应用领域有哪些
  • 网站服务器错误湖南产品网络推广业务
  • 哈尔滨网站推广公司哪家好网络营销知名企业
  • 国内做外贸网站的有哪些网站建设公司官网