C++字符串向量和数组

字符串、向量和数组

除了基本内置类型外,C++还定义了一个内容丰富的抽象数据类型库,如string、vector和迭代器。

一、    命名空间的using声明

1.  using namespace std;

2.  using std::cin;

3.  位于头文件的代码一般来说不应该使用using声明。

 

二、    标准库类型string

#include<string>

Using std::string;

1.  定义和初始化:

string s1; string s2=s1; strings3=”hello”;

string s4(10,’c’);//s4的内容是“cccccccccc

2.  如果使用“=”初始化一个变量,实际上是执行拷贝初始化,否则是直接初始化。

3.   使用getline()读取一行,只有遇到换行符才结束读取操作并返回结果。getline也会返回流参数,因此既然输入运算符可以作为判断条件,那么也能使用getline的结果作为条件。While(getline(cin,line)){},触发getline函数返回结果的那个换行符实际上是被丢弃掉了,得到的string对象中不包含换行符。

4.   string::size_type类型:size函数返回一个string::size_type类型的值,它是一个无符号类型的值,在C++11标准中允许编译器通过auto或者decltype()来推断变量的类型。由于size函数返回的是一个无符号整型数,如果在表达式中混用了带符号数和无符号数将可能产生意想不到的后果。例如,假设n是一个具有负值的int,则表达式s.size()<n的判断结果几乎肯定是true。这是因为负值n会自动地转换成一个比较大的无符号值。

5.  当把string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符两侧的运算对象至少有一个是string。编译器没法把两个字符串字面值加在一起。切记,字符串字面值和string是不同的类型

6.   在cctype头文件中定义了一组标准库函数能判断并改变某个字符的特性。如是否是字母或数字isalnum(c),是否是小数点ispunct(c)等。

7.   C语言中的头文件形式是name.h,C++中将这些文件命名为cname.特别的,在名为cname的头文件中定义的名字从属于命名空间std

8.   使用范围for语句处理每个字符(类似与java中的增强for循环)。C++11新标准提供的一种语句:范围for语句。

for(auto c : str) cout<<c<<endl;每次迭代,str的下一个字符背拷贝给c,因此该循环可以读作“对于字符串str中的每个字符c”,执行某某操作。如果要想使用范围for语句改变字符串中的字符值,需要把循环变量定义为引用类型。

9.   逻辑与运算符(&&)遵循短路原则:只有当左侧运算对象为真时才会检查右侧运算对象的情况。

10. 使用下标之前要检查其合法性,超出范围将会引发不可预知的后果。

 

三、     标准库类型vector

标准库类型vector表示对象的集合,其中所有对象的类型都相同。

C++语言既有类模板也有函数模板,其中vector是类模板。编译器根据模板创建类或函数的过程称为实例化。

1.   vector能容纳绝大多数类型的对象作为其元素,但是因为引用不是对象,所以不存在包含引用的vector。如果元素仍为vector,则在早期的标准的编译器中必须在外层vector对象的右尖括号和其元素类型之间添加一个空格。

2.   定义和初始化。使用拷贝初始化时只能提供一个初始值。如果提供一个类内初始值,则只能使用拷贝初始化和使用花括号形式。如果提供的是一个初始值列表,则只能把初始值放在花括号里进行列表初始化,而不能放在圆括号里。通常情况下,可以值提供vector对象容纳的元素数量而省去初始值。vector<int>ivec(10);//10个元素,每个初始化为0。

3.   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有2个元素,值分别为10和1;

如果用的是圆括号,可以说提供的值是用来构造vector对象的。

如果是花括号,可以表述成我们想列表初始化为该vector对象。

4.   范围for语句体内不应该改变其所遍历序列的大小。

5.   使用push_back方法添加元素而不能用下标形式添加。

6.   只能对确定已存在元素使用下标访问。通过下标访问不存在的元素的行为会导致缓冲器溢出这种常见错误。

四、     迭代器介绍

所有标准库容器都可以使用迭代器。

1.   拥有begin和end成员。Begin负责返回指向第一个元素的迭代器。End成员负责返回指向容器尾元素的下一个位置的迭代器,称作“尾后迭代器”。特殊情况下如果容器为空,则begin和end返回的是同一个迭代器。

2.   循环终止条件的写法中,C++程序员习惯性地使用!=,其原因和他们更愿意使用迭代器而非下标的原因一样:因为这种编程风格在标准库提供的所有容器中都有效。所有标准库容器的迭代器都定义了==和!=,但是它们中的大多数都没有定义<运算符。

3.   const_iterator和常量指针差不多,能读取但不能修改它所指向的元素值。相反iterator的对象可读写。如果vector对象或string对象是一个常量,则只能使用const_iterator;如果vector对象和string对象不是常量,那么既可以使用iterator也能使用const_iterator。

4.   C++11标准引入两个新函数,分别是cbegin和cend。与begin和end函数不同的是不论对象是否是常量,返回值都是const_iterator。

五、     数组

1.   定义数组时候的维度必须是一个常量表达式。

2.   定义数组的时候必须指定数组的类型,不允许使用auto关键字由初始值的列表推断类型。另外和vector一样数组元素应该为对象,故不存在引用的数组。

3.   不能用数组的内容拷贝给其他数组作为初始值,也不能用数组为其他数组赋值。

4.   要理解数组声明的含义,最好的办法是从数组的名字开始按照由内向外的顺序阅读。如:int *(&array)[10]=ptrs;//首先知道array是一个引用,然后观察右边知道,array引用的对象是一个大小为10的数组,在观察左边知道,数组的元素类型是指向int的指针。

5.   同样能够使用范围for语句和下标运算符访问数组元素。

6.   使用数组的时候编译器会把它转换成指针。在很多用数组名的地方,编译器会自动地将其替换为一个指向数组首元素的指针。。使用数组类型的对象其实是使用一个指向数组首元素的指针。

7.   在一些情况下数组的操作实际上是指针的操作。其中一层意思是当使用数组作为一个auto变量的初始值时,推断得到的类型是指针而非数组。

如:int ia[]={0,1,2,3,4,5,6,7,8,9,};auto ia2(ia);//ia2是一个整型指针,指向ia的第一个元素。类似与auto ia2(&ia[0]);当使用decltype关键字时,上述转换不会发生,返回类型为10个整数构成的数组。decltype(ia)ia3={0,1,2,3,4,5,6,7,8,9};

8.   指针也是迭代器,使用指针也能遍历数组中的元素。通过数组名字或者数组中首元素的地址都能得到指向首元素的指针。

9.   标准库函数begin与end为C++11新标准引入的函数。与容器中的两个同名成员函数功能类似。不过数组毕竟不是类类型,因此这两个函数不是成员函数,正确用法是将数组作为它们的参数。

int *beg=begin(ia);//指向数组ia中的首元素的指针

10. 标准库类型使用的下标必须是无符号类型,而内置类型的下标运算无此要求。内置的下标运算符所使用的索引值不是无符号类型,这一点与vector和string不一样。

11. C风格字符串,将字符串存放在字符数组并以空字符(null)结束。即在字符串最后一个字符后面跟一个空字符(‘\0’)。该风格函数有strlen、strcmp、strcat、strcpy等,分别表示长度,比较,添加和拷贝意思。传入此类函数的指针必须指向以字符串为结束的数组。

12. 允许使用以空字符结束的字符数组来初始化string对象或为string对象赋值;在string对象的加法运算中允许使用以空字符结束的字符数组作为其中一个运算对象(不能两个都是)。在string对象的复合赋值运算中允许使用以空字符结束的字符数组作为右侧的运算对象。上述性质反过来不成立。string专门提供一个名为c_str的成员函数完成将string对象直接初始化为指向字符的指针。而且我们无法保证c_str函数返回的数组一直有效,如果后序操作改变了string对象值就可能让之前返回的数组失去效用。

13. 使用数组初始化vector对象,只需要指明拷贝区域的首元素地址和尾后元素地址。vector<int>ivec(begin(str),end(str));

六、     多维数组

使用范围for语句处理多维数组:

int i=0;

    for(auto&row : ia)

       for(auto&cool : row){

           col=I;

++i;

}

 

    for(autop=ia;p!=ia+3;++p){

    for(auto q=*p;q!=*p+4;++q)

       cout<<*q<<’’;

cout<<endl;

}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值