前言
这一章主要介绍了string、vector和数组,知识不是很全,主要是介绍了一些需要注意的细节,如果需要了解更加详细的知识可以看书籍。
最后,如果有什么理解不对的地方,希望大家不吝赐教,谢谢!
【C++系列】【前一章:C++的一些基础知识】【下一章:函数】
二、字符串、向量和数组
1、标注库类型string
需加上头文件#include<string>
直接拷贝和拷贝初始化
string s5="hiya"; //拷贝初始化,编译器会把等号右侧的初始值拷贝到新的创建的对象中去
string s6("hiya"); //直接初始化
string读取
cin>>s; //遇到空格则停止
getline(cin,s) //读取一行,存放到s中
关于string的一些操作
- s.empty(); //判断s是否为空
- s.size(); //返回s的字符个数
Tip:如果一条表达式中已经有了size()函数就不要再使用int了,这样可以避免混用int和unsigned可能带来的问题。可以采用auto来自动判断类型
- +:两侧的运算对象至少有一个是string,用""括起来的字符串就是字面值而已并不是sting的对象
切记:字符串字面值与string是不同的类型
使用C++版本的C标准库头文件
C语言的头文件形如name.h
C++则将这些头文件命名为cname
使用基于范围的for语句
for (declaration:expression)
statement
比如:
string str("some string"); //每行输出str中的一个字符 for(auto c:str) cout<<c<<endl;
2、标准库类型vector
vector表示对象的集合,其中所用对象的类型都相同,集合中每个对象都有一个与之对应的索引,索引用于访问对象。要想使用vector,必须包含头文件#include<vector>。C++语言既有类模板,也有函数模板,其中vector是一个类模板。
Note:vector是模板而非类型,由vector生成的类型必须包含vector中元素的类型,例如vector<int>
模板本身不是类或函数,相反可以将模板看作为编译器生成类或函数编写的一份说明。编译器根据模板创建类或函数的过程称为实例化, 当使用模板时,需要指出编译器应把类或函数实例化成何种类型。提供信息的方式总是这样:即在模板名字后面跟一对尖括号,在括号内放上信息。
关于vector的一些操作
- v.push_back(value); //向v中添加元素
如果循环体内部包含有向vector对象添加元素的语句,则不能使用范围for循环,范围for语句体内不应改变其所遍历序列的大小
- v.empty(); //判断是否为空
- v.size(); //返回v中元素的个数
要使用size_type,需要先指定它是由哪种类型定义的,vector对象的类型总是包含着元素的类型。
vextor<int>::size_type //正确
vector::size_type //错误
不能用下标形式添加元素,vector对象的下标运算符可用于访问已存在的元素,而不能用于添加元素,确保下标合法的一种有效手段就是尽可能使用范围for语句。
迭代器
类似于指针类型,迭代器也提供了对对象的间接访问,就迭代器而已,其对象是容器中的元素或者string对象中的字符。有效的迭代器或者指向某个元素,或者指向容器中尾元素的下一位置,其他所用情况都属于无效。
使用迭代器
auto b=v.begin(),e=v.end(); //b表示v的第一个元素,e表示v尾元素的下一个位置,即不存在的元素
迭代器的使用和指针特别类似
迭代器类型
拥有迭代器的标准库类型使用iterator和const_iterator来表示迭代器的类型,const_iterator就和指向常量的指针一样
另外一个限制是任何一种可能改变vector对象容量的操作,比如push_back都会使该vector对象的迭代器失效,谨记,但凡使用了迭代器的循环体,都不要向迭代器所属的容器添加元素。
3、数组
如果不清楚元素的确切个数,请使用vector。数组是一种复合类型,维度必须是一个常量表达式。
int (*Parray)[10]=&arr; //首先是括号括起来部分,*Parray意味着Parray是个指针,观察右边可知道Parray是个指向大小为10的数组指针,最后观察左边,知道数组中的元素是int,这样最终确定Parray是个指向大小为10的数组的指针。
要想理解数组声明的含义,最好的办法是从数组的名字开始按照由内向外的顺序阅读
访问数组元素
使用数组下标的时候,通常将其定义为size_t类型
在大多数表达式中,使用数组类型的对象其实是使用一个指向该数组首元素的指针。
指针也是迭代器
int arr[]={0,1,2,3,4,5,6}; int *p=arr; //p指向arr的第一个元素 ++p; //p指向arr[1]
标准库函数begin和end
int ia[]={0,1,2,3,4,5,6}; int *beg=begin(ia); //指向ia首元素的指针 int *last=end(ia); //指向arr尾元素的下一位置的指针
内置的下标运算符所用的索引值不是无符号类型,这一点与vector和string不一样。可以处理负值。
混用string对象和C风格字符串
c_str函数返回值是一个C风格的字符串,如果后续的操作改变了s的值就可能让之前返回的数组失去效用,如果执行完c_str()函数后程序向一直都能使用其返回的数组,最好将该数组重新拷贝一份。
使用数组初始化vextor对象
只需要指明要拷贝区域的首元素地址和尾后地址就可以了