文章目录
第3章字符串、向量和数组
主要内容 | 功能 |
---|---|
string | 可变长字符串 |
vector | 可变长集合 |
数组 | 类似vector |
迭代器 | 类似指针 |
3.1命名空间的using声明
[!]头文件不用using
using namespace std;//全部
using std::cin;//某个
3.2标准库类型string
#include<string>
using std::string;
3.2.1定义和初始化string对象
string s1 ;
string s2 (s1);
string s2 =s1;
string s3 ("value") ;
string s3 = "value" ;
string s4(n,'c');
3.2.2 string对象上的操作
os<<s;输出流如std::cout
is>>s;输入流如std::cin
getline (is, s);
s.empty ();
s.size ();
s[n];
s1+s2;
s1=s2;
s1==s2;
s1!=s2;
<, <=, >, >=;
string s;
while(cin>>s){}//非法输入结束
//保留空白字符
while(getline(cin,s)){
if(!s.empty()){..}
if(!s.size()>1){..}
}
//size()函数返回string::size_type类型的值,无符号数
操作 | 说明 |
---|---|
size()函数 | 返回string::size_type类型的值,无符号数 |
+ | 可以拼接字符和字符串,两侧至少有一个string对象 |
3.2.3处理string对象中的字符
#include<cctype>
//cname的头文件,属于std空间
范围for
string str="aaa";
for(auto c:str){
cout<<c<<endl;
}//c为char
改变字符
for (auto &c : s)
{c = toupper(c);}
cout << s << endl;
下标运算符
输入参数:string::size_type|整数即可
返回:引用
string::size_type类型获取方法:decltype(s.size())
//例子
string s="dwa";
for(int i=0;i!=s.size();++i){
cout<<s[i]<<endl;
}
3.3标准库类型vector
#include<vector>
using std::vector//是一个类模板
vector<int> v1;
vector<Sales_item> v2;//<...>内不可以是引用,因为引用不是对象
vector<vector<int>> v3;
3.3.1定义和初始化vector对象
支持列表初始化,默认初始化,拷贝…
3.3.2向vector对象中添加元素
v.push_back(i);//添加到末尾
[!]注意范围for,{…}内部不能有添加元素的语句
3.3.3其他vector操作
操作 | 说明 |
---|---|
v.size() | 返回vector<…>::size_type类型 |
v.empty() | |
v[n] | |
= | |
==,!=,<,>,<=,>= |
范围for
//改变
for(auto &i:v){
...
}
[!]对空的vector不可以用下标添加元素
3.4迭代器介绍
支持迭代器的对象 |
---|
string |
标准库容器 |
3.4.1使用迭代器
迭代器成员 | 说明 |
---|---|
begin() | 返回第一个元素迭代器 |
end() | 返回最后一个元素的下一个位置 |
容器为空,则begin=end是同一个迭代器
扫描二维码关注公众号,回复:
10571956 查看本文章
3.4.2迭代器运算
运算符(iter是迭代器) | 说明 |
---|---|
*iter | 虽然是解引用运算符,但是返回所指元素的[引用] |
iter->成员||(*iter).成员 | 解引用获取成员 |
++,– | 移动一个单位 |
==,!=,+,-,比较 | 类型一般用auto, |
(*iter).empty() | |
iter1-iter2 | 返回距离,可正可负,difference_type |
[!]解引用必须针对合法迭代器
获取引用类型
string s("adada");
if(s.begin()!=s.end()){
auto iter =s.begin();
*iter=toupper(*iter);//*iter获取该元素的引用,可以对其修改成大写
}
for循环用!=,因为大多数标准库容器的迭代器没有<运算符
for(auto it=s.begin();it!=s.end();++it){
...
}
迭代器类型
迭代器类型 | 功能(读写) |
---|---|
vector::iterator it1; | r,w |
string::iterator it2; | r,w |
vector::const_iterator it3; | r |
string::const_iterator it4; | r |
[!]常量的迭代器一定是const_iterator
[!]begin和end的返回值视容器而定,常量返回常量迭代器,反之返回非常量迭代器,如果想返回常量迭代器,C++11引入了cbegin(),cend()
[!]使用迭代器的循环体,不能向容器添加元素
3.5数组
大小固定
3.5.1定义和初始化内置数组
维度必须是常量表达式
constexpr unsigned sz=10;
int *p[sz];//p是数组,元素是int指针
[!]函数体内部定义了数组,默认初始化会含有未定义的值
字符数组
char a1[]={'a','\0'};//长度是2
char a2[]="c";//长度是2,隐含一个'\0'
不可拷贝,赋值
//int a[]={0,1,2};
//int a2[]=a;//error
//a2=a;//error
数组的指针
int arr[]={1,2,3};
int *p=arr;//p指向arr
cout<<*p<<endl;//1
//也可以写成
int (*p2)[3]=&arr;//p2指向arr
cout<<*(*p2)<<endl;//1
cout<<*p2<<endl;//0x61fe34
cout<<p2<<endl;//0x61fe34
数组的引用
int arr[]={1,2,3};
int (&arr2)[3]=arr;
cout<<arr2[1]<<endl;//2
数组里面有指针元素
int *p[10];//p的元素是指针
int *(&p2)[10]=p;//p2是p的引用
3.5.2访问数组元素
下标类型 |
---|
size_t |
范围for
for(auto i:array){}
3.5.3指针和数组
数组名是第一个元素的地址,也是指针
int a[]={1,2,3};
auto a2(a);//a2是指向a的指针
decltype(a) a3={2,3,4};//但是decltype(a) 返回int[3]
指针也是迭代器
int a[]={1,2,3};
int *p=a;
++p;
cout<<*p<<endl;//2
int *end=&a[3];//尾后迭代器
--end;
cout<<*end<<endl;//3
标准库函数begin,end
int a[]={1,2,3};
int *be=begin(a);
int *en=end(a);
cout<<*be<<" "<<*(en-1)<<endl;//1 3
下标和指针
int a[]={1,2,3,4,5,6};
int *p=&a[2];//*p是3
int j=p[1];//相当于*(p+1),4
int k=p[-2];//可正可负,1
3.5.4 C风格字符串
#include<cstring>
拷贝,拼接c
char s1[]="";
char s2[]="wda";
strcpy(s1,s2);//copy
strcat(s1,"ss");//拼接
cout<<s1<<endl;//wdass
3.5.5与旧代码的接口
string和C风格字符串(以’\0’结束的char[])
string s3=s1;//wdass,可以赋值
s3+=s2;//"wdasswda",可以+,但是不能+两边都是char[]
[!]不可以用string初始化字符指针
字符串变字符数组
//char *p=s3;//error
const char *p=s3.c_str();//p指向s3变成的char[]
数组初始化vector
int a[]={1,2,3,44};
vector<int> v1(begin(a)+1,end(a));//2 3 44
3.6多维数组
#ifdef CONSTEXPR_VARS
constexpr size_t rowCnt = 3, colCnt = 4;
#else
const size_t rowCnt = 3, colCnt = 4;
#endif
int ia[rowCnt][colCnt];
for (size_t i = 0; i != rowCnt; ++i) {
for (size_t j = 0; j != colCnt; ++j) {
...
}
}
//范围for,外层要用auto &
for (const auto &row : ia)
for (auto col : row)
cout << col << endl;
指针和多维数组
int a[2][2]={{1,2},{3,4}};
int (&a2)[2]=a[1];//a2[2]={3,4}
int (*p)[2]=a;//*p={0,1}
遍历
#ifdef CONSTEXPR_VARS
constexpr size_t rowCnt = 3, colCnt = 4;
#else
const size_t rowCnt = 3, colCnt = 4;
#endif
int ia[rowCnt][colCnt];
for (auto p = ia; p != ia + rowCnt; ++p) {
// q points to the first element of an array of four ints;
// that is, q points to an int
for (auto q = *p; q != *p + colCnt; ++q)
...
}
for (auto p = begin(ia); p != end(ia); ++p) {
// q points to the first element in an inner array
for (auto q = begin(*p); q != end(*p); ++q)
...
}
类型别名
#ifdef TYPE_ALIAS_DECLS
using int_array = int[4]; // new style type alias declaration
#else
typedef int int_array[4]; // equivalent typedef declaration
#endif
//int_array *p=ia跟int (*p)[4]=ia一样
for (int_array *p = ia; p != ia + 3; ++p) {
for (int *q = *p; q != *p + 4; ++q)
cout << *q << ' ';
cout << endl;
}