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

无锡专业做网站的公司企业如何建立网站

无锡专业做网站的公司,企业如何建立网站,做网站界面需要注意什么,如何做网站排名优化string的使用 1.构造函数的使用2. string类对象的访问及遍历操作2.1operator[]实现遍历2.2 普通迭代器正序遍历2.3 auto/范围for2.3.1 auto2.3.2 范围for 2.4 普通迭代器逆序遍历2.5 const迭代器 3.string类对象的容量操作3.1 size和length3.2 max_siz3.3 capacity3.4 clear3.5…

string的使用

    • 1.构造函数的使用
    • 2. string类对象的访问及遍历操作
      • 2.1operator[]实现遍历
      • 2.2 普通迭代器正序遍历
      • 2.3 auto/范围for
        • 2.3.1 auto
        • 2.3.2 范围for
      • 2.4 普通迭代器逆序遍历
      • 2.5 const迭代器
    • 3.string类对象的容量操作
      • 3.1 size和length
      • 3.2 max_siz
      • 3.3 capacity
      • 3.4 clear
      • 3.5 resize
    • 4.string类对象的修改操作
      • 4.1 push_back
      • 4.2 append
      • 4.3 operator+=
      • 4.4 不同平台下string的扩容机制
      • 4.5 find和replace 替换指定字符
    • 5. 剩下的部分接口
      • 5.1 c_str
      • 5.2 refind 和 substr 取文件名的后缀

在这里插入图片描述
string是basic_string的模板char类型实现,相比于其他类型的模板实现,string是最常用的。

1.构造函数的使用

#include<iostream>
using namespace std;
int main()
{string s1; //string(); 无参构造,构造空字符串string s2("hello world"); //string(const char* s)  用C-string来构造string类对象string s3  = s2;//string(const string&s) 拷贝构造函数string s4(5, 'c');//string(size_t n, char c) string类对象中包含n个字符ccout << s1<< endl;cout << s2 << endl;cout << s3 << endl;cout << s4 << endl;return 0;
}

在这里插入图片描述

2. string类对象的访问及遍历操作

2.1operator[]实现遍历

int main()
{string s1("hello world");for (int i = 0; i < s1.size(); i++)//size()返回容器中元素的个数{cout << s1[i] << " ";}return 0;
}

在这里插入图片描述
s1[i]这里是一个函数重载,原型是s1.operator[].(i)。operator[]的实现大致如下:

char& operator[] (size_t pos){assert(pos < _size);return _str[pos];}

char&引用返回允许我们修改返回字符。
在这里插入图片描述
库函数中还实现了const版本的operator[]函数,const的string对象使用operator[]就会调用const版本的重载,当然这个版本不允许修改返回字符。

2.2 普通迭代器正序遍历

int main()
{string s1("hello world");string::iterator it1 = s1.begin();while (it1 != s1.end())//最后一个数据的下一个位置  '\0'{cout << *it1 << " ";it1++;}return 0;
}

在这里插入图片描述

  1. 迭代器的使用很像指针,有些容器的迭代器底层实现是指针,有些不是。
  2. 迭代器可以实现对字符串对象的读写。
  3. 迭代器是一种通用的方式,operator[]只适用于元素地址连续的容器。
  4. 迭代器是通过运算符重载的方式来实现的。

2.3 auto/范围for

2.3.1 auto

auto是C++11给出一个"语法糖",会自动推导类型。

int main()
{int i = 0;auto z = i;auto x = 1.1;auto p = &i;return 0;
}
int main()
{int& r1 = i;auto r2 = r1; //int auto& r3 = r1; //int& r1的引用
}

auto无法推导出引用,r1是i的引用,但是r2并不是r1的引用,这里的quto r2 = r1等价于int r2 = r1,可以使用auto&来解决问题。
在这里插入图片描述
另外 auto 需要被初始化,auto r4;这样无法推导类型,是错误的。下面将体现auto的使用价值。

int main()
{//auto的价值1:方便   auto it1 = list1.begin();std::map<std::string, std::string> dict;//std::map<std::string, std::string>::iterator;auto dit = dict.begin();
}

这样就可以替代写起来很长的类型,可以简化代码。

2.3.2 范围for

C++范围for也是C++11的一个语法糖,用来遍历容器,底层是迭代器 当底层支持迭代器的时候,才可以使用范围for
如何使用范围for遍历一个string对象呢?

int main()
{string s1("hello world");//自动取容器的数据赋值给左边的值,自动判定结束,自动++;for (char ch : s1){cout << ch << " ";}return 0;
}

在这里插入图片描述
一般使用范围for的时候一般搭配auto使用,上面的例子可以写为for(auto ch: s1)

string s1("hello world");
for (char ch : s1)
{cout << ch << " ";
}
cout << endl;
for (char ch : s1)
{ch++;
}
for (char ch : s1)
{cout << ch << " ";
}
cout << endl;

由于范围for是把容器拷贝给auto对象,所以范围for不修改原容器。
在这里插入图片描述
可以使用引用来修改容器。

for (char& ch : s1)
{ch++; 
}

在这里插入图片描述
范围for搭配引用的使用范围

  1. 需要修改容器
  2. 类型占内存很大
  3. 类型很大同时又不想修改的时候可以考虑 const auto&

有个例外,数组也支持范围for,可以认为是编译器的特殊处理

int main()
{int a[] = { 1,2,3,4,5,6 };for (auto ae : a){cout << ae << " ";}return 0;
}

从C++20开始支持auto做参数,C++11开始就支持auto做返回值了。

auto Func(auto x)
{ ..}

但是auto做返回值,会导致程序不够清晰明了。

auto func3()
{auto y = func4();return  y;
}
auto func2()
{auto x = func3();return x;
}
int main()
{auto ret1 = func();
}

ret1的类型是什么呢?auto做返回值要谨慎使用

2.4 普通迭代器逆序遍历

如何倒叙遍历一个字符串对象呢?迭代器分为正向迭代器iterator反向迭代器reverse_iterator,反向迭代器可以实现倒叙遍历。

int main()
{string s1("hello world");auto rit = s1.rbegin();while (rit != s1.rend()){cout << *rit << " ";++rit;  //++ 不是 -- }return 0;
}

2.5 const迭代器

const对象无法使用普通的迭代器,const迭代器也无法修改原容器
与普通迭代器相同,const迭代器也分为正向迭代器const_iterator和反向迭代器const_reverse_iterator

int main()
{string s1("hello world!");const string s2(s1);//const对象无法使用普通的迭代器//auto it = s2.begin();string::const_iterator it = s2.begin();while (it != s2.end()){cout << *it << " ";++it;  //*it1 += 1;  无法修改}cout << endl;string::const_reverse_iterator it1 = s2.rbegin();while (it1 != s2.rend()){cout << *it1 << " ";++it1;//*it1 += 1;  //const迭代器无法修改}return 0;
}

在这里插入图片描述

3.string类对象的容量操作

3.1 size和length

获取string对象中的有效字符的个数

int main()
{string s1("hello world");cout << s1.size() << endl;cout << s1.length() << endlreturn 0;
}

在这里插入图片描述
size和length的功能相同,为什么要都实现出来呢,着不得不提出发展历史的原理,string的涉及比STL要早,string起初设置的是length,但是STL的都命名为size,string类也就补充了一个size,size的命名方式比lengt通用,所以推荐使用size。

3.2 max_siz

表示容器可最大申请的个数,理想化的,没有意义,在不同的环境下不同

int main()
{string s1("hello world");cout << s1.max_size() << endl;return 0;
}

在这里插入图片描述
在X86环境下,可以达到21亿多,但是实际是达不到的。

3.3 capacity

可以存储的有效字符的个数底层跟顺序表的设计类似,可实现自动扩容

int main()
{string s1("hello world");cout << s1.capacity() << endl;return 0;
}

在这里插入图片描述
这里实际存储的容量是16,有效字符的后一个位置存\0,和C语言保持一致。

3.4 clear

清除数据,一般不清除空间数据,只修改size,然后首位置改为\0,具体的实现更为复杂。

int main()
{string s1("hello world1111");s1.clear();cout << s1.size() << endl;cout << s1.capacity() << endl;return 0;
}

在这里插入图片描述
这里还有三个接口没有讲

3.5 resize

resize会有三种情况

  1. resize < size
  2. size < resize < capacity
  3. resize > capacity

第一种是一个删除的行为,第二三种就是插入的行为,第三种还涉及到扩容。

int main() //resize
{string s1("hello world");cout << s1 << endl;cout << s1.size() << endl;cout << s1.capacity() << endl;s1.resize(10);  //删除数据cout << s1 << endl;cout << s1.size() << endl;cout << s1.capacity() << endl;s1.resize(14);  //插入cout << s1 << endl;cout << s1.size() << endl;cout << s1.capacity() << endl; //调试后发现插入的是'\0',最后面一个被认为是终结符。s1.resize(20,'x'); //扩容并插入cout << s1 << endl;cout << s1.size() << endl;cout << s1.capacity() << endl;return 0;
}

在这里插入图片描述

在这里插入图片描述
如果没有设置插入的字符,默认就是\0,并且只有最后一个\0会被认定为是终结符。

4.string类对象的修改操作

这一部分也是string设计比较乱的地方

4.1 push_back

在字符串后尾插字符c

int main()
{string s1("hello");//尾插字符s1.push_back(',');s1.push_back('w');cout << s1 << endl;return 0;
}

在这里插入图片描述

4.2 append

在字符串后追加一个字符串。

int main()
{string s1("hello");s1.push_back(',');s1.push_back('w');s1.append("orld");cout << s1 << endl;return 0;
}

在这里插入图片描述
append接口有多个重载函数,可以实现很多方式的字符串尾插。
在这里插入图片描述
甚至可以插入一段迭代器区间

int main()
{string s1("hello");s1.push_back(',');s1.push_back('w');s1.append("orld");string s2("hello linux");s1.append(s2.begin()+5, s2.end());cout << s1 << endl;return 0;
}

在这里插入图片描述

4.3 operator+=

+=运算符重载可以平替上面两个接口的部分功能,是很常用的。

int main()
{string s3("hello");s3 += ',';s3 += "world";cout << s3 << endl;return 0;
}

在这里插入图片描述

4.4 不同平台下string的扩容机制

写一段代码来体现一下vs2022的string的扩容机制。

int main()
{	string s1;size_t old = s1.capacity();cout << "capacity:" << old << endl;for (size_t i = 0; i < 500; i++){s1 += 'x';if (s1.capacity() != old){cout << "capacity:" << s1.capacity() << endl;;old = s1.capacity();}}return 0;

在这里插入图片描述
首次2倍,后续都是1.5倍来扩容的。
Linux下的扩容方式为2倍扩容。
在这里插入图片描述

int main()
{	string s3("1111111");string s4("11111111111333333333333333333333333333");cout << sizeof(s3) << endl;cout << sizeof(s4) << endl;return 0;
}

在这里插入图片描述
vs的第一次为什么是2倍扩容呢?string的成员变量有一个char buffer[16],当字符的有效个数不大于15的时候,字符串实际存储在栈上,当字符串大于15时,才会到堆上开辟空间,避免了短小字符串在堆上频繁申请增加系统开销。
在这里插入图片描述
在这里插入图片描述
为了避免频繁扩容,在预先知道大约需要多少空间的时候,我们可以调用reserve接口,提前申请好容量。

int main()
{	string s5;s5.reserve(200);cout <<s5.capacity()<< endl;return 0;
}

在这里插入图片描述
reserve在vs2022下的实现开出了一个比200大的空间,也是符合使用需求的。

4.5 find和replace 替换指定字符

int main()
{string s1("hell  world ");cout << s1 << endl;size_t i = s1.find(' ');while (i != string::npos){s1.replace(i, 1, "%%");i = s1.find(' ',i+2);}cout << s1 << endl;return 0;

在这里插入图片描述

find没有找到指定字符的时候就是返回npos
find函数由于替换的时候需要循环挪动数据,所以效率很低。

如何提效呢?这里有一个空间换时间的方法。

int main()
{string s1("hell  world ");cout << s1 << endl;string s2;for (auto ch : s1){if (ch != ' ')s2 += ch;elses2 += "%%";}s1 = s2;//s1.swap(s2);cout << s1 << endl;return 0;

在这里插入图片描述

5. 剩下的部分接口

5.1 c_str

返回c格式的字符串

int main()
{string s1("hello world");cout << s1 << endl;cout << s1.c_str() << endl;return 0;
}

在这里插入图片描述
C++已经实现了流插入运算符的函数重载,可以打印出C格式的字符串了,那为什么还有提供这个接口呢?有些软件不会提供C++的接口。因为C++兼容C,c_str()可以保证C和C++混合编程。

5.2 refind 和 substr 取文件名的后缀

refind: 从字符串的pos位置向前查找,返回该字符在字符串种的位置。
substr:在str中从pos位置开始,截取n个字符,然后将其返回。

int main()
{string s1("test.cpp.zip");size_t pos = s1.rfind('.');if(pos != string::npos){string sub = s1.substr(pos);cout << sub << endl;}return 0;
}

在这里插入图片描述

http://www.dtcms.com/wzjs/182882.html

相关文章:

  • 无锡做家纺公司网站附近学电脑培训班
  • 手机制作网站的软件重庆网站开发公司
  • 那个网站教人做冰点南通企业网站制作
  • 商贸有限公司起名字唐山网站建设方案优化
  • 广州市住房建设部网站资源搜索器
  • 福田公司简介win7最好的优化软件
  • 开发板一般在周几更新seo网站推广杭州
  • 网站设计手机win7怎么优化最流畅
  • 网站建设空间一般多大市场营销平台
  • 网站建设课程 谷建软文网官网
  • wap html网站模板免费做网站怎么做网站吗
  • 深圳html5网站制作新媒体营销推广方案
  • 河北保定网站建设百度快照下载
  • 电商网站如何做引流关键词搜索工具好站网
  • 自己这么做网站重庆广告公司
  • 建设银行辽宁分行报名网站百度客服人工电话多少
  • 做的图怎么上传到网站百度竞价怎么开户
  • 网站微信支付开发广州官方新闻
  • 代刷网站怎么做关联词有哪些四年级
  • 聊城质量最好网站建设aso优化工具
  • 有做火币网这种网站的吗舆情信息怎么写
  • mugeda做网站快速申请免费个人网站
  • 做网站链接怎么弄大数据精准营销系统
  • wordpress 删除 wordpress.org四川seo推广
  • 2017做哪些网站能致富sem广告投放是做什么的
  • 河北建设局网站seo入门教程视频
  • 坪山网站建设哪家公司靠谱百度搜索推广采取
  • 济南网站制作推广cba目前排名
  • 番禺建设网站策划咨询公司
  • dw做网站时怎么改为绝对路径seo基础培训机构