string类,vector<T>,iterator迭代器,C风格字符串,数组

string可变长字符序列

初始化:

  1. 默认初始化,得到空字符串
  2. ()直接初始化,调用构造函数,当要初始化多个值,
  3. (n,'c')连续n个c字符组成的字符串
  4. =拷贝初始化,调用拷贝构造函数,只能提供一个初始值

基本API:

IO操作:

  1. cin<<a忽略开头空白(\0,\n,\t),直到下一处空白位置,读取一个字符串
  2. cin<<a<<b读取两个字符串
  3. while(cin<<a){}读取若干次的字符串,直到流无效
  4. getline(cin,a)读取字符串,保留空白,直到遇到换行符\n,也就是读取一整行
  5. while(getline(cin,a))循环读取每行

size():返回size_type类型,是一个无符号整形数

==,!=:对大小写敏感,两个运算对象包含字符完全一致

>,<,>=,<=:对大小写敏感

  1. 当一个为另一个前缀,较短的小于较长的
  2. 当逐字符比较出现相异字符,比较ASCII码,较小的值小于较大的

+:两侧运算对象至少有一个为string,不能将两个形如"a" + "b"的字面值加在一起

cctype头文件,字符处理

获取string的每个字符:[size_type]下标访问,返回第size_type索引的字符引用

vector可变长序列

vector是用于存放相同类型对象的容器,是一个类模板,因此实例化模板也要遵守规则,vector<type> name;

初始化:

  1. 默认初始化,得到空vector
  2. vector<T> v(n,val)n个重复元素,每个都是val
  3. vector<T> v(n)n个重复元素,每个元素执行值初始化
  4. 列表初始化:vector<T> v {a,b,c,......}每个元素赋予对应的值
  5. **注意:**类内初始化,仅允许使用=或{}形式,不允许()直接初始化

基本API:

v.push_back(t)向v尾端添加一个元素t

其余api和string没有太大差异,比如==,比较的也是两个vector中对应的元素,但要注意,如果元素类型为自定义类类型,且类中没有包含operator == () ,则无法对元素比较

由下标访问后获取的元素,可以支持的运算符或api仅由自身类型决定

默认初始化 vs 值初始化

| | |
|----------------|-------------------|------------------|
| 定义 | 变量被声明但没有被显式初始化时 | 使用花括号{}进行初始化 |
| 基本数据类型局部变量 | 值是未定义的(随机值) | 初始化为类型的默认值(如0) |
| 全局变量/静态变量 | 编译器赋予默认值(如int为0) | 同样被赋予默认值(如int为0) |
| 类类型变量 | 调用默认构造函数(如果存在) | 同样调用默认构造函数(如果存在) |
| 特殊行为 | 无特定初始化行为(局部变量未定义) | 聚合类型可能有不同行为 |

其他

isspace()是否是空白字符

toupper()改为大写形式

size_t类型,是与

iterator迭代器

只有少数的几种标准库容器才支持下标[]访问,但是所有的标准库容器都可以使用迭代器

迭代器类似于指针,但又和指针不同

迭代器类型:支持迭代器的标准库中,例如vector<type>::iterator或vector<type>::const_iterator类似于对常量指针,不能修改所指向元素的值

如果容器时const,则通过begin()或end()运算符返回的是const_iterator类型的迭代器

迭代器运算符:

获取迭代器:

begin():返回指向第一个元素的迭代器

end():返回指向尾元素下一位的迭代器,这种迭代器又叫尾后迭代器

cbegin():无论容器是否为常量都返回const_iterator

cend():同上

*解引用:获取指向的元素的引用

++,- -:移动到下一个或上一个元素

注意访问元素的成员时:(*it).empty(),迭代器需要加上括号

注意:t->箭头运算符 等价于(*t).这种两部操作形式

迭代器算数运算:

it + n或it - n:移动n个位置,仍然返回迭代器

关系运算符,比较两个迭代器的前后位置

it1 - it2:结果是两个迭代器的距离,

数组

也是用于存放相同类型对象的容器,但与vector不同的是,它的大小固定,不能向数组添加元素,这样的性质对运行时的性能较好,但是缺乏灵活性

基本操作

定义数组:type arr[n]; arr是一个含有n个类型为type元素的数组,注意不允许用auto自动推断

初始化:使用列表初始化

  1. 此时允许忽略数组的维度n([]空的形式)
  2. 但是如果指明了维度,那么元素总数量不应该超出指定维度
  3. 如果初始列表元素少于维度的元素,则仅通过列表初始化相应的元素,其余默认初始化

对于char类型的数组,有两种初始化的形式,一种如上列表初始化,每个元素为字符,另一种通过字符串字面值"......",这种形式会自动在结尾添加空字符串,所以要注意不能超过维度

注意:数组不允许拷贝和赋值

访问数组元素:通过下标访问,下标的类型可以为size_t类型,

**注意:**访问时要注意下标越界问题和访问非法内存问题

数组元素指针

大部分情况下,使用数组名时,会被替换为指向数组首元素的指针

对于一个指向数组元素指针,迭代器支持的操作,它全都支持,但要注意两个指针需要在同一个对象中才能进行关系运算

不过如果想作为首元素指针需要type* p = arr(替换为指向数组首元素的指针);作为尾后指针需要type* p = arr[n](索引范围为0----n-1)

但是为了放置出错,引入了标准库函数begin(arr)和end(arr)(并非容器类的成员,数组不是类)

我们说使用数组名时,会被替换为指向数组首元素的指针,因此

cpp 复制代码
int* p = arr[2];->等价于 int *x = arr; p = *(x + 2);

只要指针指向的时数组中的元素,都可以执行下标运算,因此

cpp 复制代码
int j = p[1]; ->等价于 *(p+1)

多维数组

数组的数组,阅读方式依旧遵守:由内而外,从右到左

int arr[m][n][j]需要从内到外阅读,arr是大小为m的数组,每个元素都是为n的数组,这些数组的元素又都是含有j个int类型的数组

初始化:{}内部嵌套{},但是内层是非必须的

访问方式:每个维度对于下标运算符[],如果[]的数量<维度,则返回数组,而非元素

当使用for处理每个元素时,注意使用&,为了避免数组自动转换为指针

C风格字符串和数组

C风格字符串即字符串字面值,存放在char类型的数组中,并以\0结尾,一般用指针操作

对C风格字符串,也就是\0结尾的数组,基本操作(注意和string操作方式有较大差异):

  • strlen(p):返回从 p 指向的地址开始,直到遇到第一个空字符(\0)之前的字符数(不包括该空字符)
  • strcmp(p,p1)比较这两个指针所指向的以空字符(\0)结尾的字符串在字典序上是否相等,如果相等返回0,如果返回正数,前面的较大,否则后面较大
  • strcat(p,p1)连接操作将p1附加到p后,返回p
  • strcpy(p,p1)将p1拷贝给p,返回p

注意

如果上述传入的非\0结尾,将产生未定义

如果不使用strcmp进行比较,从而比较这两个指针,而非字符串,即比较的是指针的地址,如果两个指针指向的不是同一个C风格字符串,将产生未定义

对于想要使用strcat或者strcpy,必须提供结果数组,该数组必须足够大,容纳下所有字符包括、0,因此很容易出错

通常情况会使用string而非C风格字符串

C风格字符串和string

允许C风格字符串初始化string,允许+其中一个为C风格字符串,允许+=右侧为C风格字符串,相反的这些操作都不成立

s.c_str()将string转为C风格字符串,函数返回const char *类型的指针

数组和vector

可以用数组初始化vector,vector<type> v (begin(arr), end(arr)),包含比arr多一个的元素,因为是尾后指针

相关推荐
kkk_皮蛋23 分钟前
力扣773:滑动谜题
c++
float_com1 小时前
【STL】 set 与 multiset:基础、操作与应用
c++·stl
临沂堇2 小时前
CCF刷题计划——训练计划(反向拓扑排序)
数据结构·c++·算法·拓扑·ccf
猿饵块2 小时前
cmake--get_filename_component
java·前端·c++
秋邱2 小时前
C++: 类和对象(上)
开发语言·c++
Mike!3 小时前
C++进阶 set和map讲解
java·开发语言·数据结构·c++·set·map·cpp
六点半8883 小时前
【C/C++】速通涉及string类的经典编程题
c语言·开发语言·c++·算法
汤姆和杰瑞在瑞士吃糯米粑粑3 小时前
string类(C++)
开发语言·c++
学霸小羊4 小时前
C++游戏
c++·游戏