两种标准库类型:string和vector 。string表示的一个可变长的字符序列,而vector表示的是某种给定类型对象的可变长序列。
- 直接初始化和拷贝初始化: 如果使用等号则为拷贝初始化,否则为直接初始化
string s1(“i love you”);//直接初始化
string s2(s1);//s2是s1的副本
string s3=“i love you”;//拷贝初始化
string s4(10,‘c’);//直接初始化,s4的内容为10个c
string的操作:
os<<s 将s写到输出流os中,返回值为os
is>>s 从is中读取字符串赋给s,返回值为is
getline(is,s)从is中读取一行赋给s,返回is
s.empty() s为空返回true,否则返回false
s.size() 返回字符串中字符地个数
s[n] 返回S中第n个字符地引用,n从0开始
s1+s2 返回s1和s2连接后的结果
- 多个输入和输出可以连起来写
string s1,s2;
cin>>s1>>s2; //将第一个输入读到s1中,将第二个输入读到s2中。
cout<<s1<<s2;
- 如果我们希望最终得到地结果保留一开始输入地空白符,则可以使用getline
getline(cin,line)
注意:getline函数返回的line中的那个换行符已经被丢掉了,得到地string并不包含换行符了,手动地加上换行符操作:使用命令:endl 来结束当前行并刷新显示缓冲区。
empty也是string的一个成员函数,需要调用的话,加上点运算符就可以了。 - string::size_type 类型
size函数的返回值类型是无符号整型数
注意:如果一个表达式中已有了size函数,那么就不要再使用int了,这样可以避免int和unsigned混用带来地问题。
注意:C++语言中的字符串字面值并不是标准库类型String的对象。切记,字符串字面值和string 是不同地类型。而且需要注意不能直接将两个字符串字面值相加,但是可以将字符串字面值和string相加,因为标准课允许将字符字面值和字符串字面值转换成string对象。 - 处理string对象中的字符
cctype头文件中地函数
isalnum(c)//当c是字母或者数字时为真
isdigit(c)//当c是数字时为真
isalpha(c)//当c是字母时为真
iscntrl(c)//当c是控制字符时为真
isgraph(c)//当c不是空格但可打印时为真
islower(c)当c是小写字母时为真
isprint(c)//当c是可打印字符时为真
ispunct(c)//当c是标点符号时为真
isspace(c)//当c是空白时为真
islower(c)//当c是小写字母时为真
isupper(c)//当c是大写字母时为真
isxdigit(c)//当c是十六进制时为真
tolower(c)//当c是大写字母输出对应地小写字母,否则原样输出
toupper(c)//当c是小写字母输出对应地大写字母,否则原样输出
针对于头文件而言,C++继承了C语言的标准库,在c中一般使用name.h而在c++中则为cname所以cctype等价于ctype.h的头文件。
注意:在cname的头文件中定义的名字从属于命名空间std,而定义在名为.h的头文件则不然。
处理每个字符可以使用基于范围for语句(range for)
for(declaration:expression)
statement
string str("i love you")
for( auto c:str) //c为定义地一个变量,该变量用于访问序列中地元素
cout<< c <<endl;
- 使用范围for语句改变字符串中的字符
如果想改变字符串中地值就应该将循环变量定义为引用型,这样这个变量实际上被依次绑定序列地每个元素上。使用这个引用我们就能改变它绑定地字符。
string s(“hello the world”);
for(auto &c:s)//对于s中地每个字符,需注意这里c是引用
c=toupper(c);//c是一个引用,因此赋值语句将改变s中每个字符的值
cout<< s <<endl;
- string 的下标必须大于等于0,小于s.size()
- vector 使用要包括头文件
#include<vector>
using std::vector;
vector是模板而非类型,由vector生成的类型必须包含vector 中元素地类型,例如vector<vector<int>>
**
定义在函数体之外地内置类型将不被初始化。一个未被初始化地内置类型变量的值是未定义地,如果以拷贝或者以其他形式访问此类值将会引发错误。
列表初始值还是元素数量:(圆括号和方括号地区别)
vector<int> v1(10);//v1有10个元素,每个元素的值被初始化为0
vector<int> v2{10};//v2有1个元素,为10
vector<int> v3(10,1);//v3有10个元素,每个元素地值为1
vector<int> v4{10,1};//v4有两个元素,分别为10和1
注意:如果使用地是花括号,初始化过程中会尽可能地把花括号内的值当成元素初始值地列表来处理,只有在无法执行列表初始化时才考虑其他初始化方式。
[例]:
vector<string> v5{10}//v5有10个默认初始化地元素,因为是string 所以无法使用列表初始化,只能利用这样地值构建vector对象
注意:与c语言或者Java不一样地是:vector对象能高效增长,因而在开始地时候创建空的vector对象,在运行时再动态添加元素,这样地效率要比直接在开始的时候定义指定其容量是要好的
范围for语句:
for(auto &i:v)//循环变量定义为引用,因而就像通过i给v地元素赋值。
- 要注意使用size_type,需要指定它是由哪种类型定义地,vector对象地类型总是包含着元素的类型
vector<int>::siz_type//正确
vector::size_type//错误
string::size_type//正确
- vector 的元素地添加不能使用下标地方式,这是因为vector对象的下标运算符只能用于访问已存在地元素而不能用于添加元素。
- 通过下标访问不存在地元素地行为非常常见,通常会产生很严重地错误,buffer overflow (缓冲区溢出)指的就是此类错误。这是特别值得注意的。
标准容器迭代器地运算符
*iter //返回迭代器所指元素地引用
iter->men//解引用iter并获取名为men地成员,等价于(*iter).men,这里注意如果是iter.men那么就是错误地,因为iter是迭代器,没有men成员。
++iter//令iter指示容器中地下一个元素
--iter//令iter指示容器中的下一个元素
iter1=iter2//判断两个迭代器是否相等
- 因为end返回地迭代器并不实际指示某个元素,所以不能对其进行递增或者解引用操作。
- 迭代器最重要的是解引用操作。利用* 号
只有string和vector等一些标准库类型有下标运算符,而并非全都如此。因而要学会使用迭代器。此外C++程序员喜欢使用== 和!=正是因为所有的标准库容器地迭代器都定义了这个,但是它们中的大多数却没有定义<运算符。因此在for循环中,C++和C或者Java经常不一样地地方就是使用==或者!==而不适用<,不过即使使用<号C++也是正确的。 - 拥有迭代器地标准库类型使用iterator和const_iterator来表示迭代器地类型
其中const_iterator 和常量指针一样,可读不可写。iterator可读可写 - C++中引入了cbegin和cend,这两个函数得到的是const_iterator 类型地返回值。
vector<int>::iterator it;//it能读写vector<int>中的元素
vector<int>:: const_iterator;//IT只能读不能写元素
string::iterator it;//it 可读可写string中的字符
string::const_iterator it;//it只能读字符不能写字符
谨记: 凡是使用了迭代器地循环体,都不要向迭代器所属地容器内添加元素
- difference_type是带符号整型数
数组
如果不确定元素的确切个数请使用vector。
数组的维度必须是一个常量表达式。
- 理解数组声明地含义最好地办法是从数组的名字开始按照由内向外的顺序阅读。 也就是先看括号内的然后在看右边,最后左边
- 面对一个比较复杂的指针或引用地声明语句时,从右向左阅读有助于弄清楚它的真实含义。
- C++11 中引入了标准库函数begin和end
用法和vector里面的begin和end函数有点类似,但是毕竟不是类类型所以这两个不是成员函数,因而用法如下
int ia[]={1,2,3,4,5};
int *beg=begin(ia);//指向第一个元素
int *last=end(ia);//指向的是最后一个元素地后一位置
- 使用数组下标的时候通常将其定义为size_t类型。size_t是一种机器相关地无符号类型。被定义在cstddef头文件中,在C的标准库中则定义在stddef.h头文件中。 类似的,两个指针相减地结果的类型是一种ptrdiff_t的标准库类型,它是一个带符号类型。
- 内置的下标运算符不是无符号类型,这一点是与vector和string不一样的地方。
使用范围for语句处理多维数组,除了最内层的循环外,其他地所有循环的控制变量都应该是引用类型
多维数组可以看做是数组的数组