字符串、向量、数组、迭代器


标准库类型string

  • string对象会自动忽略开头的空白(即空格符、换行符、制表符等)并从第一个真正的字符开始读起,直到遇到下一处空白为止。

  • 当我们希望得到的string对象中保留输入时的空白符时,可以用getline函数来代替原来的>>运算符。getline函数的参数是一个输入流和一个string对象,函数从给定的输入流中读入内容,直到遇到换行符为止(p78)。如:

    getline(cin,str);

  • 两个string对象相加问题:当把string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符(+)的两侧的运算对象至少有一个是string(p81),如:

string s4=s1+","; //正确
string s4=“hello”+","; //错误
string s4=s1+“,”+"world"; //正确:s1+","的结果是一个string对象

  • 使用范围for语句改变字符串中的字符:如果想改变string对象中字符的值,必须把循环变量定义成引用类型(p83),如:

    for(auto &c : s)

标准库类型vector

  • vector是模板而非类型,vector能容纳绝大多数类型的对象作为其元素,但是因为引用不是对象,所以不存在包含引用的vector(p87)。

  • 如果用圆括号,则提供的值是用来构造vector对象的,如:

    vector< int> v1(10,1); //v1有10个元素,每个值都是1

  • 如果用花括号,则表示用列表初来始化该vector对象,如:

    vector< int> v2{10,1}; //v2有2个元素,值分别是10和1

  • 如果初始化时使用了花括号的形式但是提供的值又不能用来列表初始化,就要考虑用这样的值来构造vector对象了(p89),如:

    vector< string> v3{10,"hi"}; //v3有10个值为“hi”的元素

  • 如果循环体内部包含有向vector对象添加元素的语句,则不能使用范围for循环,因为范围for语句体内不应改变其遍历序列的大小(p91)。

对于vector和string下标使用的问题

  • 关于下标必须明确的一点就是只能对确知已存在的元素执行下标操作(p94),如:

    vector< int> ivec(10);
    cout < < ivec[9]; //正确
    vector< int>ivec;
    cout< < ivec[9] //错误

迭代器

  • 对于for循环内使用!=而不是用<的说明:只有string和vectory等一些标准库类型有下标运算符,而并非全都如此。与此类似,所有标准库容器的迭代器都定义了==和!=,但是它们中大多数都没定义<运算符,因此,只要我们养成使用迭代器和!=的习惯,就不用太在意用的到底是哪种容器类型(p97)。

string s("some string");
for(auto it=s.begin(); it!=s.end();++it)
cout<<* it<<endl;

  • 迭代器的标准库类型使用iterator和const_iterator来表示迭代器的类型,对于const_iterator类型可以使用cbegin()和cend()两个函数来返回(p98),如:

auto it=v.cbegin(); //it的类型是vector< int> ::const_iterator

  • 谨记,但凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加元素!
  • c++没有定义两个迭代器的加法运算,但定义了迭代器间的减法运算、迭代器与整数间的加减运算(_p63),如:

Mid=(beg+end)/2; //非法

数组

  • 数组的维度必须是一个常量表达式。
  • 和内置类型的变量一样,如果在函数内部定义了某种内置类型的数组,那么默认初始化会令数组含有未定义的值(p101)。
  • 和vector一样,数组的元素应为对象,因此不存在引用的数组。
  • 标准库函数begin和end,如:

int a[3]={1,2,3};

int *beg=begin(a); //指向a首元素的指针。

  • 允许使用数组来初始化vector对象,但不允许使用vector对象来初始化数组(p111),如:

int int_arr[]={0,1,2,3,4,5};
vector< int> ivec(begin(int_arr), end(int_arr)); //ivec中有6个元素,分别是int_arr中对应元素的副本
Vector< int> ivec2(int_arr+1, int_arr+4) ; //这条初始化语句用3个元素创建了对象ivec2

C风格字符串

  • 对于c风格字符串的函数strlen(p)、strcmp(p1,p2)、strcat(p1,p2)、strcpy(p1,p2),传入此类函数的指针必须指向以空字符'\0'作为结束的数组(p109)。

  • 混用string对象和c风格字符串:
    (1) 允许使用一空字符结束的字符数组来初始化string对象或为string对象赋值。
    (2) 在string对象的加法运算中允许使用以空字符结束的字符数组作为其中一个运算对象(不能两个运算对象都是)
    (3) 不能用string对象直接初始化指向字符的指针,为了完成该功能,string专门提供了一个名为c_str的成员函数(p111),如:

char * str=s1; //错误,不能用string对象初始化char*
const char * str=s.c_str() //正确

  • 关于范围for循环语句:要使用范围for语句处理多维数组时,除了最内层的循环外,其他所有循环的控制变量都应该是引用类型,这样是为了避免数组被自动转换为指针(p114),如:

    for(const auto &row : ia)
    for(auto col : row)

    ​ cout<<col<<endl;

posted @ 2017-08-31 10:04  坡上樹  阅读(292)  评论(0编辑  收藏  举报