C++ Primer 读书笔记 - 2

本文详细介绍了C++中字符串的相等性和关系运算,以及如何使用for循环遍历和修改字符串中的字符。强调了string对象的比较规则以及for循环在处理序列时的工作原理。还提及了vector的声明和初始化,以及在使用vector时需要注意的细节,如元素访问和类型匹配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

字符串

相等性运算符(==和!=)分别检验两个string对象想等或不相等,string 对象相等意味着长度及所包含字符全部相同。关系运算符 <、<=、>、>=分别检验一个string对象是否小于、小于等于、大于、大于等于另一个 string 对象,依照(大小写敏感的)字典顺序:

  • 1、如果两个 string 对象的长度不同,而且较短的 string 对象的每个字符都与较长的 string 对象对应位置上的字符相同,就说较短 string 对象小于较长 string 对象
  • 2、如果两个 string 对象在某些对应的位置上不一致,则 string 对象比较的结果其实是 string 对象中第一对相异字符比较的结果。
c++11 for 语句
for (declaration : expression)
	statement

expression 部分是一个对象,表示一个序列。declaration 部分负责定义一个变量,该变量将被用于访问序列中的基础元素。每次迭代,declaration 部分的变量会被初始化为 expression 部分的下一个元素值。

使用 for 语句改变字符串中的字符

需要将循环变量定义成引用类型。

只处理一部分字符

想访问 string 对象中的单个字符有两种方式:

  • 使用下标
  • 使用迭代器
string::size_type 类型

size 函数返回一个 string::size_type 类型的值,该配套类型体现了标准库类型与机器无关的特性。具体使用时通过作用域操作符表明名字 size_type 是在类 string 中定义的。
string::size_type 是一个无符号类型的值,而且足够存放下任何 string 对象大小。同时使用该类型进行数值对比时要注意不要和带符号数混用,因为 s.size() < n 在 n 是一个负值的 int 时判断结果基本肯定为 true, 因为负数会自动转换成一个很大的无符号数。

下标运算符([ ])接受的输入参数是 string::size_type 类型的值,表示要访问的字符的位置;返回值是该位置上字符的引用。下表值必须大于等于 0 而小于 s.size(),超过范围则引发不可预知的结果

vector

  • 老式声明 vector 元素的 vector 的方式为外层 vector 对象的右尖括号和其他元素类型之间添加空格: vector<vector <int> >
  • 提供初始元素值的列表,只能把初始值都放在花括号里进行列表初始化而不能放在圆括号里:vector<string>{"a", "b"};
  • 值初始化:圆括号可用于同值的初始化vector<int> v1(10, 1) \\ 十个1的 vector,不填1则默认0。甚至在列表初始化失败时也会尝试用值初始化处理vector<string> v1{10, "hi"} \\ 十个"hi"的vector
  • 使用vector的 size_type时需要先指定它是由哪种类型定义的 vector<int>::size_type
  • 只有当元素的值可比较时,vector对象才能被比较

迭代器

基本操作

  • 迭代器用于访问容器类型的元素,有迭代器的类型都拥有 beginend 的成员,begin 负责返回指向第一个元素的迭代器,end 负责返回指向容器“尾元素的下一个位置(one past the end)的迭代器”,这个迭代器指示了一个本不存在的元素(尾后 off the end 迭代器),仅作标记作用。如果容器为空,则 beignend 都返回同一个迭代器(尾后迭代器)
  • 通过 *iter 的方式获得迭代器指向的元素,++iter--iter令迭代器指向上一个/下一个元素

迭代器类型

  • 使用 iterator const_iterator 来表示
vector<int>::iterator it;  // it能读写vector<int>里的元素
vector<int>::const_iterator it2;  // it2不能读写vector<int>里的元素
  • beignend运算符返回的具体类型由对象是否是常量决定,c++11引入了cbegincend直接获取const_iterator

解引用和成员访问

  • 需要带圆括号 (*it).empty(),或者用箭头运算符-> it->empty())。箭头运算符结合了解引用和成员访问

迭代器失效

  • 使用迭代器的循环体中改变迭代器所属容器的对象容量会导致迭代器失效

迭代器运算

  • 迭代器加减整数仍是返回迭代器,表示移动了多少个位置。
  • 两个迭代器相减获得之间的距离,类型是 difference_type 的带符号整型数。

数组

  • 数组不允许拷贝和赋值
  • 复杂声明,对数组而言从数组名开始内向外阅读,再从右到左
int *ptrs[10];  // ptrs是指向10个整型指针的数组
int &refs[10] = /* ?*/;  // 错误:不存在引用的数组
int (*Parray)[10] = &arr  // Parray指向一个含有10个整型的数组
int (&arrRef)[10] = arr  // arrRef引用一个含有10个整型的数组
int *(&arry)[10] = ptrs;  // arry是数组的引用,该数组有是个整型指针
  • 使用数组下标时通常定义为size_t类型,与机器无关的无符号类型,被设计的足够大以便表示内存中任意对象的大小。
  • 数组名本身可替换成一个指向数组首元素的指针
int ia[] = {0,1,2}
auto ia2(ia); // ia2 是个整型指针,指向ia的第一个元素,类似auto ia2(&ia[0])
decltype(ia) ia3 = {0, 1, 2};  // ia3是含有3个整型数的数组,decltype不会自动转换
  • 指针也是迭代器,可通过指向数组元素的指针自增获取下一位元素。但获取尾后指针需要int *e = &arr[length],用越界一位的下标获取。
  • c11引入了beginend两个标准库函数,能方便获取头指针和尾后指针
int *beg = begin(ia);
int *end = end(ia);
  • 两个指针相减的结果类型为ptrdiff_t的带符号类型,和size_t一样定义在 cstddef 头文件中,是机器相关的类型。
  • 指针指向同一个数组的元素时可以比较大小
  • 下标运算符可以处理负值
int *p = &ia[2];
int j = p[1];  // p1等价*(p+1),即ia[3]
int k = p[-2];  // p[-2]即ia[0]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值