松原公司做网站网页app
- 作者: 五速梦信息网
- 时间: 2026年04月20日 08:25
当前位置: 首页 > news >正文
松原公司做网站,网页app,网站建设 阿里云,在线定制logo【C初阶】string类 #x1f955;个人主页#xff1a;开敲#x1f349; #x1f525;所属专栏#xff1a;C#x1f96d; #x1f33c;文章目录#x1f33c;
- 为什么学习string类#xff1f; 1.1 C语言中的字符串 1.2 实际中
- 标准库中的string类 2.1 string类 2.…【C初阶】string类 个人主页开敲 所属专栏C 文章目录
- 为什么学习string类 1.1 C语言中的字符串 1.2 实际中
- 标准库中的string类 2.1 string类 2.2 auto和范围for 2.3 string类常用接口说明
- string类的模拟实现 3.1 经典的string类问题 3.1.1 浅拷贝 3.2.2 深拷贝 3.2 string类模拟实现 1. 为什么学习string类 1.1 C语言中的字符串 C语言中字符串是以\0结尾的一些字符的集合为了操作方便C标准库中提供了一些str系列 的库函数但是这些库函数与字符串是分离开的不太符合OOP的思想而且底层空间需要用户 自己管理稍不留神可能还会越界访问。 1.2 实际中 在我们日常的刷题中有关字符串的题目基本上是以string的形式出现的并且在日常的生活当中为了简单、方便快捷基本上也都是使用的string很少有人使用C标准库中的字符串操作函数。
- 标准库中的string类 2.1 string类 string - C Reference (cplusplus.com) 这里面有关于string类的详细说明包括它的每个接口的功能以及接口的使用环境等。其中比较重要的接口有operator、iterators有关的begin、end的所有接口(自己实现时子需要实现begin、end即可后面的rbegin和rend等理解即可)、size、resize、capacity、reserve、clear、empty、operator[]、operator、append、push_back、insert、erase、swap、c_str、find、find_first_of 2.2 auto和范围for auto关键字 在这里补充两个C11的小语法方便我们后面的学习 ① 在早期C/C中auto的含义是使用auto修饰的变量是具有自动存储器的局部变量后来这个不重要了。C11中标准委员会变废为宝赋予了auto全新的含义即auto不再是一个存储类型 指示符而是作为一个新的类型指示符来指示编译器auto声明的变量必须由编译器在编译时期 推导而得也就是说auto能够自动识别对象的类型。 ② 用auto声明指针类型时用auto和auto*没有任何区别但用auto声明引用类型时则必须加 ③ 当在同一行声明多个变量时这些变量必须是相同的类型否则编译器将会报错因为编译器实际只对第一个类型进行推导然后用推导出来的类型定义其他变量。 ④ auto不能作为函数的参数可以作为返回值但是建议谨慎使用 ⑤ auto不能直接用来声明数组 看到这里你可能觉得auto没什么作用我知道我想要的是什么类型的我为什么还要它自动识别。别着急后面你就会明白auto是有多好用。 范围for: ① 对于一个有范围的集合而言由程序员来说明循环的范围是多余的有时候还会容易犯错误。因此C11中引入了基于范围的for循环。for循环后的括号由冒号“ ”分为两部分第一部分是范围内用于迭代的变量第二部分则表示被迭代的范围自动迭代自动取数据自动判断结束。 for(auto变量 : 迭代范围) { //循环体 } ② 范围for可以作用到数组和容器对象上进行遍历 ③ 范围for看似非常智能很厉害实际上底层就是迭代器(迭代器是什么后面会讲此处记住即可) 2.3 string类常用接口说明
- string的常见构造函数 2. string类对象的容量(Capacity)操作 size(重点)返回字符串有效字符长度 length返回字符串有效字符长度 capacity返回所开空间总大小 empty(重点)检查字符串是否为空 clear(重点)仅删除数据而不销毁空间 reserve(重点)为字符串预留一块空间可以数据量小时可以省去开辟空间的消耗 rsize(重点)将有效的字符减为n(自己传)个如果是增加则多加的字符改为c(自己传) 注 ① size()与length()方法底层实现原理完全相同引入size()的原因是为了与其他容器的接 口保持一致一般情况下基本都是用size()。 ② clear()只是将string中有效字符清空不改变底层空间大小。 ③ resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个不 同的是当字符个数增多时resize(n)用0来填充多出的元素空间resize(size_t n, char c)用字符c来填充多出的元素空间。注意resize在改变元素个数时如果是将元素个数 增多可能会改变底层容量的大小如果是将元素个数减少底层空间总大小不变。 ④ reserve(size_t res_arg0)为string预留空间不改变有效元素个数当reserve的参 数小于string的底层空间总大小时reserver不会改变容量大小(Linux环境下会改变但不会影响数据的存储)。
- string类对象的访问及遍历操作 operator返回pos位置字符的引用(方便修改)const string类调用 beginend(重点)begin获取字符串开头第一个字符的迭代器end获取最后一个字符下一个位置的迭代器 //后面还有rbeginrend、crbegincrend、cbegincend等迭代器这里不一一赘述 4. string类对象的修改操作 push_back(重点)在字符串后尾插一个字符 append(重点)在字符串后尾插一个字符串 operator(重点)重载运算符可以完成尾插操作 c_str(重点)返回字符串地址 findnpos(重点)从字符串pos位置开始往后查找所要字符并返回其所在位置。如果遍历完字符串也找不到则返回npos rfind从字符串pos位置开始往前查找所要字符并返回其所在位置。如果找不到则返回npos substr从字符串pos位置开始截取n个字符并返回 注 ① 在string尾部追加字符时s.push_back© / s.append(1, c) / s c三种的实现方式差 不多一般情况下string类的操作用的比较多操作不仅可以连接单个字符还可 以连接字符串。 ② 对string操作时如果能够大概预估到放多少字符可以先通过reserve把空间预留 好这样可以节剩开辟空间的效率消耗。
- string类非成员函数 operator尽量少用因为传值返回导致深拷贝导致效率降低 operator(重点)输入运算符重载用于方便输出string字符串中的内容 operator(重点)输入运算符重载 getline(重点)获取一行字符串遇到\0才会停止获取在OJ的字符串题中很常用 relational operators(重点)大小比较重载了各种类型的比较运算符 3. string类的模拟实现 3.1 经典的string类问题 3.1.1 浅拷贝 浅拷贝也称位拷贝编译器只是将对象中的值拷贝过来。如果对象中管理资源最后就会导致 多个对象共享同一份资源当一个对象销毁时就会将该资源释放掉而此时另一些对象不知道该 资源已经被释放以为还有效所以当继续对资源进项操作时就会发生发生了访问违规。 例如一个家庭中有两个孩子但父母只买了一份玩具两个孩子愿意一块玩则万事大吉万一不想分享就你争我夺玩具损坏。 3.2.2 深拷贝 如果一个类中涉及到资源的管理其拷贝构造函数、赋值运算符重载以及析构函数必须要显式给 出。一般情况都是按照深拷贝方式提供。 3.2 string类模拟实现 //string.h头文件的声明 #pragma once #include iostream #include assert.h using namespace std; namespace gjk { class string { public: typedef char* iterator; string(const char* s ) { _str new char[strlen(s) 1]; strcpy(_str, s); _size strlen(s); _capacity _size; } char operator { assert(pos _size); return _str[pos]; } const char operator const { assert(pos _size); return _str[pos]; } size_t size() { return _size; } const size_t size() const { return _size; } size_t capacity() { return _capacity; } const size_t capacity() const { return _capacity; } char* c_str() { return _str; } //迭代器 iterator begin() { return _str; } const iterator begin() const { return _str; } iterator end() { return _str _size; } const iterator end() const { return _str _size; } string() { delete[] _str; _str nullptr; _size _capacity 0; } //扩容 void dilatancy(int newcapacity); //预留空间 void reserve(size_t n); //改变有效字符数 void rsize(size_t n, char ch \0); //尾插 void push_back(char ch); //尾插字符串 void append(const char* s); //指定插入字符 void insert(size_t pos, char ch); //指定删除n字符 void erase(size_t pos,size_t n npos); //指定插入字符串 void insert(size_t pos, const char* s); //清除数据 void clear(); //判空 bool empty(); //一个字符运算符重载 string operator(char ch); //字符串运算符重载 string operator(const char* s); //比较运算符重载 bool operator(const string s); bool operator(const string s); bool operator(const string s); bool operator(const string s); bool operator(const string s); bool operator!(const string s); //找到字符第一次出现的位置 int find(char ch,size_t pos 0); //找到字符串第一次出现的位置 int find(const char* s, size_t pos 0); private: char* _str; size_t _size; size_t _capacity; const static size_t npos -1; }; } //string.cpp文件的定义 #define _CRT_SECURE_NO_WARNINGS 1 #include string.h namespace gjk { //扩容 void string::dilatancy(int newcapacity) { char* tmp new char[newcapacity 1]; strcpy(tmp, _str); delete[] _str; _str tmp; _capacity newcapacity; } //预留空间 void string::reserve(size_t n) { if (n _capacity) { char* tmp new char[n 1]; strcpy(tmp, _str); delete[] _str; _str tmp; _capacity n; } } //改变有效字符数 void string::rsize(size_t n, char ch) { if (n _size) { _size n; _str[_size] \0; } else { while (_size ! n) { if (_size _capacity) dilatancy(_capacity 0 ? 4 : 2 * _capacity); _str[_size] ch; } _str[_size] \0; } } //尾插 void string::push_back(char ch) { if (_size _capacity) dilatancy(_capacity 0 ? 4 : 2 * _capacity); _str[_size] ch; _str[_size] \0; } //尾插字符串 void string::append(const char* s) { int len strlen(s); if (_size strlen(s) _capacity) dilatancy(_size len 2 * _capacity ? _size len : 2 * _capacity); strcpy(_str _size, s); _size len; } //指定插入字符 void string::insert(size_t pos, char ch) { assert(pos _size); if (_size _capacity) dilatancy(_capacity 0 ? 4 : 2 * _capacity); size_t end _size 1; while (end pos) { _str[end] _str[end - 1]; end–; } _str[pos] ch; _size; } //指定删除n个字符 void string::erase(size_t pos,size_t n) { assert(pos _size); if (n _size - pos||n npos) { _str[pos] \0; _size - (_size - pos); } else { size_t end pos n; while (end _size) { _str[pos] _str[end]; } _size - n; } } //指定插入字符串 void string::insert(size_t pos, const char* s) { assert(pos _size); int len strlen(s); if (_size strlen(s) _capacity) dilatancy(_size len 2 * _capacity ? _size len : 2 * _capacity); size_t end _size len 1; while (end - len pos) { _str[end] _str[end - len - 1]; end–; } memcpy(_str pos, s, len); _size len; } //清除数据 void string::clear() { _str[0] \0; _size 0; } //判空 bool string::empty() { return _size 0; } //一个字符运算符重载 string string::operator(char ch) { push_back(ch); return this; } //字符串运算符重载 string string::operator(const char s) { append(s); return *this; } //比较运算符重载 bool string::operator(const string s) { return strcmp(_str, s._str) 0; } bool string::operator(const string s) { return strcmp(_str, s._str) 0; } bool string::operator(const string s) { return !(*this s || *this s); } bool string::operator(const string s) { return !(*this s); } bool string::operator(const string s) { return !(*this s); } bool string::operator!(const string s) { return !(this s); } //找到字符第一次出现的位置 int string::find(char ch,size_t pos) { assert(pos _size); while (_str[pos] ! ch pos _size) { pos; } if (pos _size) return -1; return pos; } //找到字符串第一次出现的位置 int string::find(const char s, size_t pos) { assert(pos _size); int len strlen(s); while (_str[pos] ! s[0] pos _size) { pos; } if (pos _size||_size-pos len) return -1; int ret memcmp(_str pos, s, len); if (!ret) return pos; return -1; } } 创作不易点个赞呗蟹蟹啦
相关文章
-
松溪网站建设单一产品企业或多元化产品企业的网站建设与策划有什么不同?
松溪网站建设单一产品企业或多元化产品企业的网站建设与策划有什么不同?
- 技术栈
- 2026年04月20日
-
松江醉白池网站建设wordpress小说网站模板
松江醉白池网站建设wordpress小说网站模板
- 技术栈
- 2026年04月20日
-
松江专业做网站公司php网站开发设计模式
松江专业做网站公司php网站开发设计模式
- 技术栈
- 2026年04月20日
-
嵩明建设局网站哪些网站可以免费发广告
嵩明建设局网站哪些网站可以免费发广告
- 技术栈
- 2026年04月20日
-
搜狗网站优化软件上海集团网站建设公司好
搜狗网站优化软件上海集团网站建设公司好
- 技术栈
- 2026年04月20日
-
搜狗站长平台验证不了国际新闻今天
搜狗站长平台验证不了国际新闻今天
- 技术栈
- 2026年04月20日
