C++ primer 第三章 字符串 向量 数组

1. string(可变长字符串)

1.1 字符串定义与初始化

初始化的几种形式:
(1)拷贝初始化: =
(2)直接初始化:()
(3)列表初始化: {}

注意:初始化时 (1)等号可以用于直接初始化与列表初始化
(2)用字符串字面值初始化时,不会将其中’\0’拷贝进去。

1.2 字符串对象的操作

	os<<s;//返回os
	is>>s;//返回is(忽略开头空白(即空格符,换行符,制表符))
	getline(is,s);//从is中读取一行给s(一行即is中遇到换行符为止,不忽略开头的空白符,除换行符外其余空白符均赋给对象s),返回is
	s.empty();
	s.size();
	s1+s2//返回连接结果
	s+字符字面值or字符串字面值//字面值将自动转换为字符串对象。注意:等号两边至少有一个字符串对象。
	s1==s2;
	s1!=S2;
	< <= > >=;

1.3 如何处理字符串中的字符

1.3.1 处理与改变字符

1.范围for语句加上处理(改变)语句,例如cctype文件中的一些函数。

string str("somr string");
forauto c: str)
{

}//每次迭代,str下一个字符会拷贝赋值给c;故要想改变字符值,需将c定义为引用。

注意:范围for语句中不能为序列添加或删除元素(字符),因为范围for语句为序列预留了end()的值,一旦添加删除,end()值就可能无效(即不表示任何元素)。
2.使用下表运算符[]。
注意:
(1)[]接收参数是string::size_type类型的值,返回的是一个引用。
(2) 在使用[]之前,需要检验那个位置的确有值。
3.使用迭代器

迭代器是一种数据类型,并且只有它这种类型能执行某套操作(寻找容器(string)对象的元素,能从一个元素(字符)移动到另一个元素(字符))

2. vector (可变长对象集合)

2.1 vector是一个类模板

如何给一个类模板提供信息来实例化类?

 通过在模板名字后跟一对尖括号,尖括号内放上信息。

如何给一个函数模板提供信息来实例化函数?

 通过实参。

2.2 定义和初始化vector对象

初始化的几种形式:
(1)拷贝初始化: =
(2)直接初始化:()
(3)列表初始化: {}
(4)借助数组与迭代器初始化
== 等号可以用于直接初始化与列表初始化==
注意:初始化时有三种例外:

  1. 类内初始化不能用(),会造成函数声明的歧义;
  2. 列表元素值的初始化只能用{},而不能用();
    因为初始化的真实含义因为()与{ }的不同而不同,前者提供的值用来construct(构造)vector 对象;后者的值为我们列表化初始值,会尽可能把{ }中的值当成元素初始值进行初始 化。
	vector<int> a{10};//表示a有一个元素,该元素值为10
	vector<int> a{1020};//表示a有两个元素,元素值为10,20
	vector<int> a(10);//表示a有10个元素,每个都是默认初始化值0
	vector<int> a(10,20);//表示a有10个元素,每个元素值都为20

在无法用{ }中值执行列表初始化时编译器才会考虑用这些值构造vector对象。

	vector<string> a{10,"kobe"};//显然不能用int值来初始化string,所以尽管是花括号,但却是被编译器用来构造vector对象a。
  1. 使用=时,只能提供一个初始值;

然而实际上c++标准要求vector能在代码运行时高效快速的添加元素,因此除非vector 对象所有元素值都一样时用上述初始化方法,否则更有效的方法是:先定义一个空的vector,再在运行时向它添加具体值(如利用vector成员函数 push_back() )。

2.3 vector操作

	a.empty()
	a.size()//返回值为 vector<Type>::size_type,不是vector::size_type
	a.push_back()//不能在范围for循环中为vector对象添加元素。
	a[n]//返回值为a中第n个元素的引用,n为size_type型,同样是vector<Type>::size_type,不是vector::size_type;且a不是空vector,即下表运算符不能用来添加元素,只能改变元素。
	a1==a2 //两者元素数量相同且值一样,前提是只有vector中的元素定义了比较操作
	a1!=a2
	<,<=,>,>=//以字典顺序比较

3.数组 (固定变量集合)

数组与C语言中一致,只需要注意:
1. auto 关键字不能用于数组来推断数组元素类型。
2. 数组的元素为对象,故不存在引用的集合。
3. 要理解数组声明的含义,从数组名开始,由里及外,根据优先级顺序阅读.
例如: int *(&array)[10] 表示array是一个引用,该引用对象是一个数组,数组元素是int型指针.
4.不同于容器,数组的下表运算符[]可以接收负数 ,例如a[-2]表示指向a[0]前面的第二个元素。

	int ia[]={0,1,2,3,4};
	int *p=&ia[2];
	int k=p[-2];//p[-2]是ia[0]表示的那个数。

但是不建议这样书写,因为a[-1]的地址是不确定的, 可能会影响到系统运行。如果同上面一题一样加上指针,可以巧妙地解决某些问题。
5.使用范围for处理多维数组时,除了最内层的循环变量外,其余循环的控制变量都要声明为引用类型。

	constexpr size_t row = 2, col = 3;
	int array[row][col] = { 1,2,3,4,5,6 };
	for ( const auto &a : array)//如果不声明为引用,a变成int*型,则在第二层循环中遍历指针了。
		for (const auto b : a)
			cout << b<<' ';

或者改用decltype声明。

	constexpr size_t row = 2, col = 3;
	int array[row][col] = { 1,2,3,4,5,6 };
	for ( decltype(array[0]) a : array)//decltype将array[0]看作含有四个整型数据的数组类型
		for (auto b : a)
			cout << b<<' ';
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值