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

手工艺品网站建设方案西安知名高端网站建设服务企业

手工艺品网站建设方案,西安知名高端网站建设服务企业,wordpress 移动端网页,西安vi设计公司欢迎来到我的Blog#xff0c;点击关注哦#x1f495; 前言#xff1a; C中STL扮演着极其重要的角色#xff0c;学习C重中之重的就是学习STL#xff0c;虽然string不作为containers的其中一员#xff0c;但是也是值得学习的le类。下面就进行string的模拟实现 string的模拟…欢迎来到我的Blog点击关注哦 前言 C中STL扮演着极其重要的角色学习C重中之重的就是学习STL虽然string不作为containers的其中一员但是也是值得学习的le类。下面就进行string的模拟实现 string的模拟实现和顺序表是差不多就是增加了C的特性。 string 模拟实现 存储结构 结构上使用命名空间mystr进行封装防止与库冲突使用class封装成为对象string: 定义 _size 方便记录string的大小。定义 _capacity方便记录string的容量大小定义 char* _str是存储数据进行动态new出空间nopsnpos用于表示在字符串中未找到所查找的子串或者表示一个超出字符串长度的有效索引位置。npos的值通常被定义为std::size_t类型的最大值这是一个无符号整数类型因此npos实际上是一个非常大的正整数用于表示没有找到匹配项或字符串的结束位置. namespace mystr {class string{public:static const size_t npos -1;private: size_t _size;size_t _capacity;char* _str;}; }默认构造函数 构造函数 全缺省的构造函数也是默认构造函数结尾给常量字符串末尾存在\0; 默认构造函数全缺省、无参、编译器默认生成的构造函数称之为默认构造函数 采取初始化列表对于常量引用可以进行初始化。strlen计算出大小初始化_size 2. 注意初始化顺序就是声明的顺序这个也是为什么将char* _str放在最后_capacoty初始化容量1的目的是给\0开辟空间最后将str进行拷贝这里采用memcpy不采用strcpy 3. memcpy可以将全部内容拷贝strcpy会识别\0停止假使字符串hello\0 world构造就不会得到我们想要的结果 string(const char* str ):_size(strlen(str)), _capacity(_size), _str(new char[_capacity 1]){ memcpy(_str, str, _capacity 1);}拷贝构造函数 众所周知的是当不存在拷贝构造函数编译器会自动生成拷贝构造函数 编译器生成的仅仅会实现数值上的拷贝浅拷贝_strnew出空间要实现内容上的拷贝深拷贝 _capacoty初始化容量1的目的是给\0开辟空间 string(const string s) {_capacity s._capacity;_size s._size;_str new char[s._capacity1];memcpy(_str, s._str, _capacity1); }赋值运算符重载 赋值预算符重载的底层逻辑是和拷贝构造函数是一样的在这里就不过多介绍了 string operator(const string s) {_capacity s._capacity;_size s._size;_str new char[_capacity 1];memcpy(_str, s._str, _capacity 1);}析构函数 程序的整个历程开辟空间不进行空间的释放不是一个好的习惯这里析构函数就要上场了 ~string() {_size 0;_capacity 0;delete[] _str;_str nullptr; }迭代器iterator string的迭代器的本质就是指针根据C语言的指针很容易就可以理解就是将 char * 进行 typefed char* iterator 迭代器实现两个版本 const和非const 只读和可读可写 begin iterator begin() {return _str; }iterator begin()const {return _str; }end iterator end() {return _str _size; }iterator end()const {return _str _size; }容量capacity size mstr::string类定义了_size直接将其返回 size_t size()const { return _size; }capacity mstr::string类定义了_capacity直接将其返回 size_t capacity() const {return _capacity; } resize resize是将后面指定大小初始化指定的字符缺省\0进行容量的检查不够扩容一层循环初始化为ch修改_size长度为n void resize(size_t n,char ch \0) {if (n _size){_str[n ] \0;_size n;}else{reverse(n);for (size_t i _size; i n; i){_str[i] ch;}_str[_size] \0;_size n;}}reverse 由于很多地方进行复用需要在函数内部进行判断提高效率开辟一个大于原始空间的新的空间将 _str拷贝过去改变_str的指向将新开辟的空间释放谨防内存泄漏 void reverse(size_t n) {if (n _capacity){char* tmp new char[n 1];memcpy(tmp, _str, _capacity 1);delete[] _str;_capacity n;_str tmp;}}empty 直接判断_size是否为0即可 bool empty()const { return _size 0 ? true : false; }clear 直接将首位置赋值为\0修改_size大小即可 void clear() {_str[0] \0;_size 0; }修改modify push_back Cstring中 push_back 函数声明void push_back (char c);在字符串后追加一个字符 开始要检查容量 进行扩容这里用 reverse 实现由于一个字符仅仅需要在_size位置上直接赋值在_size1的位置上赋值\0 void push_back(char ch) {if (_size _capacity){reverse(_capacity 0 ? 4 : _capacity * 2);}_str[_size] ch;_str[_size 1] \0;_size; }append append后面追加一个字符可以进行复用 push_backappend后面追加一个字符串和添加一个string类是一样的思路是一样 //追加一个字符 void append(const char ch) { push_back(ch); } //追加一个字符串 void append(const char* str) { size_t len strlen(str); if (_size len _capacity) { reverse(_capacity len); } memcpy(_str _size, str, len 1); } //追加一个string类 void append(const string str) { if (_size str._size _capacity) { reverse(_size str._size); }memcpy(_str _size, str._str, str._size1); }operator 由于是实现了append实现运算符重载就方便跟多功能一样结果一样直接进行复用 //追加一个字符 string operator (const char* str) {append(str);return *this; } //追加一个字符串 string operator (const string str) {append(str._str);return *this; } //追加一个string类 string operator (char ch) {push_back(ch);return *this; }inset 实现两个版本插入字符和插入字符串 string类是没有实现push_front头插入insert就有很大的作用了在pos位置进行插入 首先进行pos位置的断言保证pos在字符串的有效位置 进行容量检查进行扩容. 将pos位置后面的字符以及pos位置依次向后面移len个长度在pos位置插入字符字符串 i! npos在for循环中如果i变成了0之后再去减1 size_t下的-1会变为无线大会陷入死循环。 最后不要忘记将_size进行修改 //插入字符 string insert(size_t pos, char c) {assert(pos _size);if (_capacity _size){reverse(_size1);}for (size_t i _size; i pos i! npos; i--){_str[i 1] _str[i];}_str[pos] c;_size;return *this; } //插入字符串 string insert(size_t pos, const char* str) {assert(pos _size);size_t len strlen(str);if (_capacity _size){ reverse(_size len);}for (size_t i _size; i pos i! npos; i--){_str[i len] _str[i];}memcpy(_str pos, str, len);_sizelen;return *this;}erase 首先进行pos位置的断言保证pos在字符串的有效位置 erase是在pos位置删除len个字符缺省值npos 函数主体进入进len的判断如果len npos 或 pos len _size超出字符串的长度就是从pos后全部删除 否则没有超过将pos len位置后面的数据将 pos位置移动直至移动到\0 string erase(size_t pos, size_t len npos) {assert(pos _size);if (len npos || pos len _size){_str[pos] \0;_size pos;}else{size_t end pos len;while (end _size){_str[pos] _str[end];}_size - len;}}swap 利用C库中的swap进行string类的交换 void swap(string s) { string tmp(s); std::swap(_str, tmp._str); std::swap(_size, tmp._size); std::swap(_capacity, tmp._capacity); }元素访问Element access operator [ ] 实现const和非const两种只读和可读可改充分利用字符串特性可以进行下标的访问 //const char operator[](size_t index) {assert(index _size);return _str[index]; } //nonconst const char operator[](size_t index)const {assert(index _size);return _str[index]; }字符串操作String operations c_str 直接返回_str const char* c_str() {return _str; }find 首先进行pos位置的断言保证pos在字符串的有效位置字符串查找利用C语言中的strstr函数进行查找返回下面的下标利用指针减指针的方法没有找到返回npos size_t find(const char* s, size_t pos 0) const {assert(pos _size);char* p strstr(_str, s);if (p){return p - _str;}else{return npos;}}关系运算符(relational operators) 进行比较的重载 实现 其他的进行复用即可使用memcpy进行比较比较字符串较小的那个_size s._size ?_size : s._size返回 为 0 返回比较长_size s._size的那个否则返回假 ret 0 //重载 bool operator(const string s) {int ret memcmp(_str, s._str, (_size s._size ?_size : s._size));return ret 0 ? _size s._size : ret 0; } //重载 bool operator(const string s) {return _size s._size memcmp(_str, s._str, _size); } //重载 bool operator(const string s) {return !(*this s); } //重载 bool operator(const string s) {return !(*this s); } //重载 bool operator(const string s) {return !(*this s); } //重载! bool operator!(const string s) {return !(*this s); }流提取和插 operator 这个函数是写在类外面的一个友元函数使用范围for进行实现 ostream operator(ostream out, const mystr::string s) {for (auto ch : s){out ch;}return out; }operator s.clear();这句话是清理缓冲区上次cin的残留第一个while循环是处理缓冲区的空格创建一个数组避免多次开辟空间直至大小到128拷贝会加到string s 中最后的if语句是字符遇见空格或者换行结束末尾添加\0 istream operator(istream in, string s) {s.clear();char ch in.get();// 处理前缓冲区前面的空格或者换行while (ch || ch \n){ch in.get();}char buff[128];int i 0;while (ch ! ch ! \n){buff[i] ch;if (i 127){buff[i] \0;s buff;i 0;}ch in.get();}if (i ! 0){buff[i] \0;s buff;}return in; }mystr:: string 源码 #pragma once#includeiostream#includestring.h #include assert.h #include stdlib.husing namespace std;namespace mystr {class string{friend ostream operator(ostream _cout, const mystr::string s);friend istream operator(istream _cin,mystr::string s);public:typedef char* iterator;typedef const char* const_iterator;string(const char* str ):_size(strlen(str)), _capacity(_size), _str(new char[_capacity 1]){ memcpy(_str, str, _capacity 1);}//析构函数~string(){_size 0;_capacity 0;delete[] _str;_str nullptr;}// 拷贝构造函数string(const string s){_capacity s._capacity;_size s._size;_str new char[s._capacity1];memcpy(_str, s._str, _capacity1);}//赋值预算符重载string operator(const string s){_capacity s._capacity;_size s._size;_str new char[_capacity 1];memcpy(_str, s._str, _capacity 1);}const char* c_str(){return _str;}//迭代器iterator begin(){return _str;}iterator end(){return _str _size;}iterator begin()const {return _str;}iterator end()const{return _str _size;}//capacitysize_t size()const{return _size;}size_t capacity() const{return _capacity;}void reverse(size_t n){if (n _capacity){char* tmp new char[n 1];memcpy(tmp, _str, _capacity 1);delete[] _str;_capacity n;_str tmp;}}void resize(size_t n,char ch \0){if (n _size){_str[n ] \0;_size n;}else{reverse(n);for (size_t i _size; i n; i){_str[i] ch;}_str[_size] \0;_size n;}}bool empty()const{return _size 0 ? true : false;}//access//modifyvoid push_back(char ch){if (_size _capacity){reverse(_capacity 0 ? 4 : _capacity * 2);}_str[_size] ch;_str[_size 1] \0;_size;}void append(const char ch){push_back(ch);}void append(const char* str){size_t len strlen(str);if (_size len _capacity){reverse(_capacity len);}memcpy(_str _size, str, len 1);}void append(const string str){if (_size str._size _capacity){reverse(_size str._size);}memcpy(_str _size, str._str, str._size1);}string operator (const char* str){append(str);return *this;}string operator (const string str){append(str._str);return *this;}string operator (char ch){push_back(ch);return *this;}void clear(){_str[0] \0;_size 0;}void swap(string s){string tmp(s);std::swap(_str, tmp._str);std::swap(_size, tmp._size);std::swap(_capacity, tmp._capacity);}//relational operatorsbool operator(const string s){int ret memcmp(_str, s._str, (_size s._size ?_size : s._size));return ret 0 ? _size s._size : ret 0;}bool operator(const string s){return _size s._size memcmp(_str, s._str, _size);}bool operator(const string s){return !(*this s);}bool operator(const string s){return !(*this s);}bool operator(const string s){return !(*this s);}bool operator!(const string s){return !(*this s);}// 返回c在string中第一次出现的位置size_t find(char c, size_t pos 0) const{assert(pos _size);for (size_t i pos; i _size; i){if (_str[i] c){return i;}}return npos;}// 返回子串s在string中第一次出现的位置size_t find(const char* s, size_t pos 0) const{assert(pos _size);char* p strstr(_str, s);if (p){return p - _str;}else{return npos;}}// 在pos位置上插入字符c/字符串str并返回该字符的位置string insert(size_t pos, char c){assert(pos _size);if (_capacity _size){reverse(_size1);}for (size_t i _size; i pos; i--){_str[i 1] _str[i];}_str[pos] c;_size;return *this;}string insert(size_t pos, const char* str){assert(pos _size);size_t len strlen(str);if (_capacity _size){ reverse(_size len);}for (size_t i _size; i pos; i--){_str[i len] _str[i];}memcpy(_str pos, str, len);_sizelen;return *this;}string erase(size_t pos, size_t len npos){assert(pos _size);if (_capacity _size){reverse(_size len);}if (len npos || pos len _size){_str[pos] \0;_size pos;}else{size_t end pos len;while (end _size){_str[pos] _str[end];}_size - len;}}private: size_t _size;size_t _capacity;char* _str;public:const static size_t npos;};const size_t string::npos -1;ostream operator(ostream out, const mystr::string s){for (auto ch : s){out ch;}return out;}istream operator(istream in, string s){//清除缓冲区s.clear();char ch in.get();while (ch || ch \n){ch in.get();}char buff[128];int i 0;while (ch ! ch ! \n){buff[i] ch;if (i 127){buff[i] \0;s buff;i 0;}ch in.get();}if (i! 0){buff[i] \0;s buff;}return in;}}
http://www.hkea.cn/news/14300277/

相关文章:

  • wordpress建电商网站安全的合肥网站建设
  • 网站产品介绍页面的布局方案建立公司网站要多少钱
  • 爱站工具包深圳西乡
  • 做网站和SSH网站字体标准
  • 网站主机的选择与优化cc域名注册
  • 智慧团建网站维护什么时候结束做网站必须要虚拟主机吗
  • 西昌城乡建设网站四川政务服务网
  • 学网站制作电商网站设计案例
  • 网站注册页面跳出怎么做wordpress没有水印
  • 怎么看一个网站是否是外包做的重庆正云环保工程有限公司网页制作
  • 西安汇友网站建设室内设计家装设计
  • c 做网站用什么框架电商网站建设精英
  • 高端网站建设 引擎技网络宝安网站设计网站建设哪家快
  • 哪里的网站建设wordpress企业模板中文版
  • 分类信息网站建设多少钱在线培训系统平台
  • 概念产品设计网站网站ip pv
  • 宁波做网站的公司哪家好自助提交网站
  • 意大利之家设计网站找网站开发公司需要注意那几点
  • 做seo网站营销推广树莓派怎么打开 wordpress
  • 常州市建设局网站资质网站建设的类型有几种
  • 手机网站 jquery 特效龙华做网站怎么样
  • 如何让商家建设网站企业模板wordpress
  • 新产品开发流程和步骤怎么关键词优化网站
  • 石家庄网站优化公司wordpress歌曲
  • 网站关键词没有指数唐山网站优化
  • 动易网站 价格怎么开平台
  • 全球最好的黄页网站上海网站建设公司 红威
  • 深圳网站建设深圳wordpress前台配色
  • 德阳市建设局网站地址合肥网站开发建设
  • 网站开发过程的需求分析自己开通一个网站需要多少钱