命名空间的using声明
- 每个名字都需要独立的using声明
using std::cin;
using std::endl;
- 头文件不应包含using声明
标准库类型string
要包含的头文件
#include <string>
using std::string;
定义和初始化string对象
初始化写法 | 初始化方式 |
---|
string s1 | 默认初始化,s1是一个空串 |
string s2(s1) | s2是s1的副本,直接初始化 |
string s2=s1 | 等价于s2(s1),拷贝初始化 |
string s3(“value”) | 直接初始化 |
string s3=“value” | 等价于s3(“value”),拷贝初始化 |
string s4(n,‘c’) | 直接初始化 |
string对象上的操作
操作 | 作用 |
---|
os<<s | 将s写到输出流os,并返回os |
is>>s | 从is中读取字符串赋给s,遇到空白停止,返回is |
getline(is,s) | 从is中读取一行赋给s,返回is |
s.empty() | s是否为空,空为true,非空为false |
s.size() | 返回s中的字符的个数 |
s[n] | 返回s中第n个字符串的引用 |
s1+s2 | 返回s1和s2连接后的结果 |
s1=s2 | 将s2的副本拷贝s1 |
s1==s2 | 是否完全一样 |
s1!=s2 | 是否不相同 |
<,<=,>,>= | 利用字符在字典中的顺序进行比较,对大小写敏感 |
//读未知数量的string对象
string word;
while(cin>>word)
cout<<word<<endl;
//读整行
string line;
while(getline(cin,line))
cout<<line<<endl;
//字面值和string对象相加,+左右必有一个string对象
string s1="hello",s2="word";
string s3=s1+","+s2+'\n';//从左到右依次连接
处理string对象中的字符
常用函数(头文件) | 作用 |
---|
isalpha(a) | 当a是字母时为真 |
isdigit(a) | 当a是数字时为真 |
islower(a) | 当a是小写字母时为真 |
isupper(a) | 当a是大写字母是为真 |
tolower(a) | a若为大写字母,转为小写;否则不变 |
toupper(a) | a若为小写字母,转为大写;否则不变 |
- 使用范围for访问或修改string(访问auto,修改auto &)
//输出string对象
string str("some string");
for(auto c:str)
cout<<c<<endl;
// 修改string对象
for(auto &c:s)
c=toupper(str);
cout<<s<<endl;
for(decltype(str.size()) index=0;index!=s.size()&&!isspace(s[index]);++index)
s[index]=toupper(s[index]);
标准库类型vector
定义和初始化vector对象
#include <vector>
using std::vector;
写法 | 作用 |
---|
vector<T>v1 | v1是一个空vector,默认初始化 |
vector<T>v2(v1) | 直接初始化 |
vector<T>v2=v1 | 拷贝初始化 |
vector<T>v3(n,val) | 直接初始化,n个重复元素val |
vector<T>v4(n) | 直接初始化 |
vector<T>v5{a,b,c.,d,…} | 直接初始化,a,b,c,d,…为元素 |
vector<T>v5={a,b,v,d,…} | 拷贝初始化 |
vector<int>v1(10); //v1有10个元素,每个值都是0
vector<int>v2{10}; //v2有1个元素,10
vector<int>v3{10,1}; //v3有2个元素
vector<int>v4(10,1); //v4有10个1
vector<string>v6("hi"); //错误
vector<string>v7{10}; //比较特殊,v7有10个默认初始化的元素,不是列表初始化
vector<string>vl7(10);//和上面等价
vector<string>v8{10,"hi"}; //比较特殊,v8有10个值为"hi"的元素,不是列表初始化
vector<string>v8(10,"hi");//和上面等价
向vector中添加元素
- 使用push_back()函数
- 当循环体内部包含向vector对象添加元素的语句,则不能使用范围for循环
其它vector操作
操作 | 作用 |
---|
v.empty() | 是否为空,空为true |
v.size() | 返回v中元素的个数 |
v.push_back(t) | 向v的尾端添加一个值为t的元素 |
v[n] | 返回v中第n个位置上元素的引用 |
v1=v2 | 用v2中元素拷贝替换v1中的元素 |
v1={a,b,c…} | 用列表中元素的拷贝替换v1中的元素 |
v1==v2 | v1和v2相等当且仅当它们的元素数量相同且对应位置的元素都相同 |
<,<=,>,>= | 以字典顺序进行比较 |
- 用循环访问元素尽量用范围for,避免出现下标非法访问
迭代器介绍
使用迭代器
迭代器运算符 | 作用 |
---|
*iter | 返回迭代器iter所指元素的引用 |
iter->mem | 等价于(*iter).mem |
++iter | 令iter指示容器的下一个元素 |
–iter | 令iter指示容器的上一个元素 |
iter1==iter2 | 两个迭代器指示的是否是同一个元素 |
迭代器运算
数组
定义和初始化内置数组
访问数组元素
- 数组的下标定义为size_t类型,实质为无符号数,在<cstddef>头文件中定义
- 数组使用时要注意下标越界问题
指针和数组
- 使用数组类型的对象就是使用数组首元素的指针
- 标准库函数begin和end的使用(C++11),可以写出和迭代器类似的元素访问代码
- 举例
int ia[]={0,1,2,3,4,5,6,7,8,9}
// 写法1
for(int i=0;i<10;++i)
cout<<ia[i]<<endl;
// 写法2
for(int *p=ia;p!=&ia[10];++p)
cout<<*p<<endl;
// 写法3
for(auto p=begin(ia);p!=end(ia);++p)
cout<<*p<<endl;
C风格字符串
- 字符串字面值是C风格字符串,而不是string类型,存放在字符数组中要以空字符结束
C风格字符串函数 | 作用 |
---|
strlen(p) | 返回p的长度,空字符不算 |
strcmp(p1,p2) | 返回p1和p2的相等性。如果p1==p2,返回0;如果p1>p2,返回一个正值,否则,返回一个负值。 |
strcat(p1,p2) | 将p2附加到p1之后,返回p1 |
strcpy(p1,p2) | 将p2拷贝给p1,返回p1 |
与旧代码的接口
- string对象和C风格字符串
// C风格转string
string s("Hello World");// 初始化
s="Hello";//赋值
// string转C风格
const char *str=s.c_str();
- 使用数组初始化vector对象
int arr[]={1,2,3,4,5,6,7,8};
vector<int> ivec(begin(arr),end(arr)); //很简洁,之前自己可能写一个for循环
vector<int>subvec(arr+1,arr+3);//两个元素,2,3
多维数组
- 多维数组的初始化
// 里面的花括号可去
int ia[2][3]={
{0,2,3},
{2,3,4}
};
- 多维数组的下标引用
int (&row)[3]=ia[1];
- 使用范围for语句处理多维数组
size_t cnt=0;
for(auto &row:ia) //必须是引用,如果不是&,row为首元素指针,里面的for循环会出错
for(auto &col:row){
col=cnt;
++cnt;
}