S03字符串、向量和数组

S03字符串、向量和数组


一、命名空间的using声明

1、using namespace::name;:可以直接访问命名空间namespace中的名字name而不需要前缀

注意:每个名字都需要独立的声明,且头文件中不应包含using声明

二、标准库类型string

1、初始化

string s1;        //默认初始化,s1是空串
string s2(s1);    //s2是s1的副本
string s3 = s1;   //s3是s1的副本
string s4("a");   //s4是字面值的副本
string s5 = "a";  //s5是字面值的副本
string s6(n, "a");//s6初始化为连续n个a

注意:拷贝初始化是将等号右侧的初始值拷贝到新创建的string对象中,直接初始化则没有拷贝

2、string主要操作参考cppreference

3、读写string对象

  • cin >> s;自动忽略开头的空白,从第一个有效字符读直到遇到第一个空白即停止,如输入" hello world "最后s为"hello"
  • getline(cin, line);连续读入直到遇到换行符(换行符也读入)并将读入内容除换行符外存入到line中

4、size()函数返回无符号整型数,因此在有size()的表达式中尽可能避免使用int

    decltype(s1.size()) t;  //size()的返回值实际为std::size_type类型
    t = -1;
    cout << t << endl;      //输出4294967295

5、+:两个string对象可以直接相加;字面值与string对象相加必须确保+左右至少有一个string对象

string s = "hello" + s0 + "world"; //正确
string s = "hello" + "world" + s0; //错误

注意:为了与C兼容,C++中的字符串字面值并不是string对象,两者是不同的类型

6、范围for(range for):

for ( declaration : expression) 
    statement
  • expression是一个对象,表示一个序列(在statement中不应该存在改变expression序列的语句);
  • declaration定义一个变量,用于访问序列中的基础元素
string str("some string");
for(auto c : str)            //对于str中的每个字符,每次迭代将下一个字符赋给c
    cout << c << endl;       //输出some string

注意:有时候在循环中声明为引用时(如auto &c)可以避免因元素类型很大导致的拷贝开销很大

三、标准库类型vector

1、vector:表示对象的集合,其中所有对象的类型都相同,也称为容器,vector是模板而非类型

2、初始化

vector<T> v1                //v1是空vector,它潜在的元素是T类型的,执行默认初始化
vector<T> v2(v1)            //v2中包含有v1所有元素的副本
vector<T> v2 = v1           //等价于v2(v1)
vector<T> v3(n, val)        //v3包含了n个重复的val元素
vector<T> v4(n)             //v4包含了n个重复的执行了值初始化的对象
vector<T> v5{a, b, c}       //v5包含了初始值个数的元素,每个元素赋予相应的初始值
vector<T> v6 = {a, b, c}    //等价于v5{a, b, c}

圆括号:提供的值用来构造vector对象
花括号:提供的值用来列表初始化vector对象

注意:使用拷贝初始化(”=”)时只能提供一个初始值
注意:如果提供的是类内初始值,则只能用拷贝初始化或花括号形式初始化
注意:如果提供的是初始元素的列表,则只能在花括号中列表初始化,不能使用圆括号

3、对vector使用范围for时需要确保不会改变vector的序列

4、vector主要操作主要操作参考cppreference

四、迭代器介绍

1、begin返回指向第一个元素的迭代器,end返回指向尾元素下一个元素的迭代器,当容器为空时,begin和end返回同一个迭代器,都是尾后迭代器

2、迭代器的比较只能发生在同一个容器的迭代器之间,不同容器的迭代器不能比较

3、iterator主要操作参考cppreference

注意:iterator的<,<=等比较基于两个迭代器在容器中的相对位置给出结果

注意:由于迭代器的特殊性,所有使用到迭代器的循环体,都不能改变迭代器所属的容器,否则会使迭代器失效

五、数组(内置数组类型)

1、数组的大小不变,不能增减元素,当元素个数不定时使用vector,数组基本用法与vector一致

2、定义数组时必须指明数组的类型,不允许使用auto来推断,数组的元素是对象

3、字符数组需要注意结尾’\0’

char a1[] = {'C', '+', '+'};        //没有空字符
char a2[] = {'C', '+', '+', '\0'};  //有空字符
char a3[] = "C++";                  //自动添加空字符,效果和a2[]相等

4、对数组名的操作很多情况下可以认为是对常量指针的操作
(1)由于对数组的操作很多情况下被转换为对指针的操作,因此当auto数组名时实际定义是指针

int ia[] = {0, 1}, ic[] = {2};
auto ib(ia);           //实际执行过程类似auto ib(&ia[0]),且auto忽略顶层const,因此ib是int*
ib = 42;               //错误,ib是指针int*并被初始化与ia相同
ib = ic;               //正确,此时ib指向ic[0]

(2)然而当decltype数组名时实际定义的是数组,因为decltype不会转换为&ia[0]

int ia[] = {0, 1};
decltype(ia) ib;    //此时ib是指向两个int元素的数组,即ib的类型是int[2]

5、指针也是迭代器,数组的指针可以完成迭代的操作,但与类类型略有区别

int ia[] = {0, 1, 2};
int *beg = begin(ia);  //获取首元素指针
int *en = end(ia);     //获取尾后指针,尾后指针不能解引用和递增

6、下标运算符所用到的索引值不是无符号类型,可以是负数,但结果是要仔细考虑的

7、尽可能使用vector、string而不是内置数组类型

六、多维数组

1、使用范围for处理多维数组

for(auto &row : ia)
    for(auto &col : row)
        statements  //对数组元素进行操作,需要引用

for(const auto &row : ia)
    for(auto col : row)
        statements  //对数组元素只读,可以不引用,但是外层for依然需要引用,避免数组被自动转化成指针

for(auto row : ia)
    for(auto col : row)
        statements  //错误,外层循环自动将row转化成int*指针,内层循环试图在int*指针中遍历是错误的

注意:处理多维数组时,除了最内层循环外,其他控制变量都应该是引用类型

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值