您的位置:首页 > 编程语言 > C语言/C++

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)

{...}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: