c++ primer学习(二)string, vector, array
2016-07-20 15:39
267 查看
好久没写,今天开始整理c++ primer第五版的第三章。几个容器。
其实当初给我很大动力抛弃c学习c++就是实现算法时,使用了vector,这玩意太好用了。那么吧。
using声明
平时最常用的是using namespace std;不过这样子包含的太多,有可能自己写个函数就被占用了。推荐的方式是using namespace::name;比如:using std::cin;using std::string;
tip,头文件里最好不要有using声明。因为使用该头文件的文件也会继承using。
string 可变长字符序列
1.定义和初始化
string s;//默认初始化,空串
string s = s1;//拷贝式
string s = "yilan";//拷贝字面值,等于string s("yilan");不过前式为拷贝初始化,后式为直接初始化
string s(10,'c');//重复赋值,赋10个c
2.操作
读写:os<<s is>>s,如cin>>s;cout<<s;注意读写只取第一个空白和第二个空白的部分。如“wang yilan”只取"wang"。
读取任意个:while(cin>>s){;}直到碰到eof或自己写一个break。
getline:读一行。遇到换行符(之前是任意空白符)才会结束读取。如while(getline(cin,s)){;}这样就一直读取输入的每一行。
size:使用:s.size()。返回对象是string::size_type类型。可以用auto控制。不过此类型是一个无符号整型数(unsigned int),所以不能对2个size()做减法,有可能产生负数而影响结果(unsigned负数求模取余)。
empty:使用:s.empty()。返回bool值
比较:>,<,>=,<=,==,!=。字符是否相同->长度
相加:1.+。s1+s2。2.和字面值相加。必须保证字面值两侧最少有一个string。如 "hello"+","+s 就是错的(字面值不能相加)。但是s+","+"wang"是对的,因为上式=(s+",")+"wang"。注,字符串字面值不是string类型。
处理:(函数)
isalnum(c)c是数字或字母时为真
isalpha(c)字母为真
iscntrl(c)控制字符为真
isdigit(c)数字为真
isgraph(c)不是空格,但可打印
islower(c)小写字母为真
isupper(c)大写为真
isprint 可打印(c是空格或为可视形式)
ispunct 标点符号
isspace 空白符
isxdigit 16进制数字
tolower(c) 大写转小写
toupper(c) 小写转大写
范围for语句
for(声明:表达式)。如string s("aaa");for (auto c:s){...}便可以遍历字符串。可以参考Python中for语句。个人认为是c++11中巨大的改进。
如果想改变字符,则可以使用引用,如:for(auto &c:s)。因为引用是绑定在元素上的。
下标运算符[]
大于0小于s.size()。
vector
1.使用方式vector<int> x;类型是vector<int>,x中对象的类型是int。
2.定义和初始化
vector<t> v //默认
vector<t> v(x) //v拷贝x。注意v和x类型要一致
vector<t> v=x //同上
vector<t> v(n,val) //n个val
vector<t> v(n) //n个。又名“值初始化”
vector<t> v{a,b,c..} //包含了a,b,c。即列表初始化。
vector<t> v={a,b,c...} //同上
3.操作
添加元素:v.push_back(i);(删除元素是v.erase(x))
v.empty()
v.size()//v中元素个数
4.索引
下标[ ](注:空vector不能使用下标赋值,只能使用push_back)。
迭代器
容器(包括vector)都支持迭代器。string不算容器但也支持。迭代器是一种复杂的指针。
1.使用:auto b = v.begin(), e = v.end();begin指向第一个元素;end指向最后一个的下一位置,不可被调用。
2.操作:*iter 解引用
iter->mem 解引用并获取名为mem的成员=(*ietr).mem
++iter,--iter 指向下一个元素
iter1==iter2 看2个迭代器是否相等,经常在遍历时使用。如:for(auto it=v.begin(); it!=v.end();it++){...}
3.迭代器类型:2种:iterator 和const_iterator。如:vector<int>::iterator it; string::const_iterator it;
begin和end的只读形式:cbegin()和cend()。
4.解引用
如(*it).empty(),查看it的对象(*it)是否为空。可简化为:it->empty()。
5.运算
1)所有标准库容器都有支持递增的迭代器,也有执行==和!=的。
2)string和vector支持的迭代器运算更多:
iter+n iter-n
iter+=n iter-=n
iter1-iter2 >,<,>=,<=(由迭代器的位置判断,在前的小)。
数组
大小不变不能添加元素。维度必须是常量表达式。
字符数组的初始化:char a[ ]={'c','+','+'};char a[ ]={'c','+','+','\0'};char a[ ]="c++";是正确的。char a[3]="c++"是错误的。尾处有一个空字符。
不存在引用的数组,如int &ref[10]=...。但有引用的数组如int (&ref)[10]=array;引用一个10个整数的数组。
复杂指针举例:int *(&array)[10]=ptr;含义是array是一个引用,引用的对象包含10个int型指针。
访问元素:
数组下标一般定义为size_t类型,在cstddef头文件中。遍历数组依然可以使用范围for语句。
指针和数组:
指针指向数组名==指向第一个元素string *p=num;等价于string *p=&num[0];
指针也是迭代器。(之前好像说过迭代器是复杂的指针。。这看你的入门语音是什么吧)
数组的函数begin()和end()。因为数组不是类类型,所有没有成员函数。使用方法:int *beg=begin(array); int *last=end(array);
2个指针相减得到的是他们的距离,类型是ptrdiff_t。也在cstddef中。
c风格字符串:
是字符数组+空字符构成的。
1.cstring中的函数:
strlen(p)计算p的长度,不计算空字符
strcmp(p1,p2)比较p1>p2则返回正值
strcat(p1,p2)p2添加在p1后,返回p1
strcpy(p1,p2)将p2拷贝给p1,返回p1
tip,不能使用<,>等比较2个字符数组,因为这样比较的是2个指针,无意义。也不能使用类似a=strcat(p1,p2)的语句。
2.可以将string转化为旧式字符数组:成员函数:.c_str()如:const char *str=s.c_str();但不一定结果正确。
3.使用数组初始化vector对象:vector<int> ivec(begin(array),end(array));或者一部分:vector<int> vec(array+2,array+5);
多维数组
概念就不讲了。
多层嵌套使用(假设有a[2][3]):
使用指针解引用时(举例):int *p[3]=a;p=&a[0];cout<<*(*p+1);让p为有3个int元素的指向a的指针->让p指向a的第一行->输出。
for(size_t i=0;i!=rowli++)
for(size_t j=0;j!=column;j++)
{...}
使用范围for的嵌套:
for(auto &row:array) //若不使用引用则会将row自动定义为指向array首元素的指针。
for(auto &column:row)
//若内层不写数据则可不使用引用。
{...}
使用auto来减少一个*:
for(auto p=a;p!=a+2;++p)
for(auto q=*p;q!=*p+4)
{...}
其实当初给我很大动力抛弃c学习c++就是实现算法时,使用了vector,这玩意太好用了。那么吧。
using声明
平时最常用的是using namespace std;不过这样子包含的太多,有可能自己写个函数就被占用了。推荐的方式是using namespace::name;比如:using std::cin;using std::string;
tip,头文件里最好不要有using声明。因为使用该头文件的文件也会继承using。
string 可变长字符序列
1.定义和初始化
string s;//默认初始化,空串
string s = s1;//拷贝式
string s = "yilan";//拷贝字面值,等于string s("yilan");不过前式为拷贝初始化,后式为直接初始化
string s(10,'c');//重复赋值,赋10个c
2.操作
读写:os<<s is>>s,如cin>>s;cout<<s;注意读写只取第一个空白和第二个空白的部分。如“wang yilan”只取"wang"。
读取任意个:while(cin>>s){;}直到碰到eof或自己写一个break。
getline:读一行。遇到换行符(之前是任意空白符)才会结束读取。如while(getline(cin,s)){;}这样就一直读取输入的每一行。
size:使用:s.size()。返回对象是string::size_type类型。可以用auto控制。不过此类型是一个无符号整型数(unsigned int),所以不能对2个size()做减法,有可能产生负数而影响结果(unsigned负数求模取余)。
empty:使用:s.empty()。返回bool值
比较:>,<,>=,<=,==,!=。字符是否相同->长度
相加:1.+。s1+s2。2.和字面值相加。必须保证字面值两侧最少有一个string。如 "hello"+","+s 就是错的(字面值不能相加)。但是s+","+"wang"是对的,因为上式=(s+",")+"wang"。注,字符串字面值不是string类型。
处理:(函数)
isalnum(c)c是数字或字母时为真
isalpha(c)字母为真
iscntrl(c)控制字符为真
isdigit(c)数字为真
isgraph(c)不是空格,但可打印
islower(c)小写字母为真
isupper(c)大写为真
isprint 可打印(c是空格或为可视形式)
ispunct 标点符号
isspace 空白符
isxdigit 16进制数字
tolower(c) 大写转小写
toupper(c) 小写转大写
范围for语句
for(声明:表达式)。如string s("aaa");for (auto c:s){...}便可以遍历字符串。可以参考Python中for语句。个人认为是c++11中巨大的改进。
如果想改变字符,则可以使用引用,如:for(auto &c:s)。因为引用是绑定在元素上的。
下标运算符[]
大于0小于s.size()。
vector
1.使用方式vector<int> x;类型是vector<int>,x中对象的类型是int。
2.定义和初始化
vector<t> v //默认
vector<t> v(x) //v拷贝x。注意v和x类型要一致
vector<t> v=x //同上
vector<t> v(n,val) //n个val
vector<t> v(n) //n个。又名“值初始化”
vector<t> v{a,b,c..} //包含了a,b,c。即列表初始化。
vector<t> v={a,b,c...} //同上
3.操作
添加元素:v.push_back(i);(删除元素是v.erase(x))
v.empty()
v.size()//v中元素个数
4.索引
下标[ ](注:空vector不能使用下标赋值,只能使用push_back)。
迭代器
容器(包括vector)都支持迭代器。string不算容器但也支持。迭代器是一种复杂的指针。
1.使用:auto b = v.begin(), e = v.end();begin指向第一个元素;end指向最后一个的下一位置,不可被调用。
2.操作:*iter 解引用
iter->mem 解引用并获取名为mem的成员=(*ietr).mem
++iter,--iter 指向下一个元素
iter1==iter2 看2个迭代器是否相等,经常在遍历时使用。如:for(auto it=v.begin(); it!=v.end();it++){...}
3.迭代器类型:2种:iterator 和const_iterator。如:vector<int>::iterator it; string::const_iterator it;
begin和end的只读形式:cbegin()和cend()。
4.解引用
如(*it).empty(),查看it的对象(*it)是否为空。可简化为:it->empty()。
5.运算
1)所有标准库容器都有支持递增的迭代器,也有执行==和!=的。
2)string和vector支持的迭代器运算更多:
iter+n iter-n
iter+=n iter-=n
iter1-iter2 >,<,>=,<=(由迭代器的位置判断,在前的小)。
数组
大小不变不能添加元素。维度必须是常量表达式。
字符数组的初始化:char a[ ]={'c','+','+'};char a[ ]={'c','+','+','\0'};char a[ ]="c++";是正确的。char a[3]="c++"是错误的。尾处有一个空字符。
不存在引用的数组,如int &ref[10]=...。但有引用的数组如int (&ref)[10]=array;引用一个10个整数的数组。
复杂指针举例:int *(&array)[10]=ptr;含义是array是一个引用,引用的对象包含10个int型指针。
访问元素:
数组下标一般定义为size_t类型,在cstddef头文件中。遍历数组依然可以使用范围for语句。
指针和数组:
指针指向数组名==指向第一个元素string *p=num;等价于string *p=&num[0];
指针也是迭代器。(之前好像说过迭代器是复杂的指针。。这看你的入门语音是什么吧)
数组的函数begin()和end()。因为数组不是类类型,所有没有成员函数。使用方法:int *beg=begin(array); int *last=end(array);
2个指针相减得到的是他们的距离,类型是ptrdiff_t。也在cstddef中。
c风格字符串:
是字符数组+空字符构成的。
1.cstring中的函数:
strlen(p)计算p的长度,不计算空字符
strcmp(p1,p2)比较p1>p2则返回正值
strcat(p1,p2)p2添加在p1后,返回p1
strcpy(p1,p2)将p2拷贝给p1,返回p1
tip,不能使用<,>等比较2个字符数组,因为这样比较的是2个指针,无意义。也不能使用类似a=strcat(p1,p2)的语句。
2.可以将string转化为旧式字符数组:成员函数:.c_str()如:const char *str=s.c_str();但不一定结果正确。
3.使用数组初始化vector对象:vector<int> ivec(begin(array),end(array));或者一部分:vector<int> vec(array+2,array+5);
多维数组
概念就不讲了。
多层嵌套使用(假设有a[2][3]):
使用指针解引用时(举例):int *p[3]=a;p=&a[0];cout<<*(*p+1);让p为有3个int元素的指向a的指针->让p指向a的第一行->输出。
for(size_t i=0;i!=rowli++)
for(size_t j=0;j!=column;j++)
{...}
使用范围for的嵌套:
for(auto &row:array) //若不使用引用则会将row自动定义为指向array首元素的指针。
for(auto &column:row)
//若内层不写数据则可不使用引用。
{...}
使用auto来减少一个*:
for(auto p=a;p!=a+2;++p)
for(auto q=*p;q!=*p+4)
{...}
相关文章推荐
- C++设计语言三大难点
- C语言--二维数组与指针浅谈
- C++中类的组合与构造函数
- <C++略识>之浅拷贝与深拷贝
- C++ vector用法初记
- C语言实现队列
- C语言实现栈
- c++11中的线程、锁和条件变量
- Cpp环境【OpenJudge3344】【Vijos2874】冷血格斗场
- c语言链表初始化
- 在visual Studio上使用C#调用非托管C++生成的DLL文件(图文讲解)
- C语言表驱动法编程实践
- <C++略识>之对象数组与对象成员
- <C++略识>之构造函数及初始化列表
- Leetcode 198. House Robber (Easy) (cpp)
- Spiral Matrix II
- leetcode_c++:栈:Valid Parentheses(020)
- c++中this详解
- Cpp环境【Usaco2.1.3】【Vijos1222】顺序排分数
- C++经典题目上