C++学习笔记(三)
来源:互联网 发布:搜房网软件 编辑:程序博客网 时间:2024/06/05 17:38
第三章 字符串、向量和数组
1.两种最重要的标准库类型:string 和 vector。前者表示可变长的字符序列,后者存放的是某种给定类型对象的可变长序列。
2.using namespace :: name命名空间的using声明。
std::cin 的意思是要使用命名空间std中的名字cin。
头文件不应包含using声明。
标准库类型string (使用string类型必须首先包含string头文件) string定义在命名空间中 #include<string> using std::string
1.定义和初始化string类型
string a; //默认初始化为空字符串 string = "zifuchuan";
使用=号 执行的是拷贝初始化,相反不使用则为直接初始化。如果要初始化的值有很多,则用直接初始化 string a("zifuchuan"); string a(10,'c');
2.string对象上的操作
(1)读写操作
string对象对自动忽略开头的空白(空格、换行、制表符)并从第一个真正的字符开始读起,直到遇到下一个空白。
读取未知数量的string对象: string word; while(cin>>word);
(2)getline(is, s) 从is中读取一整行赋给s返回is
第一个参数是一个输入流cin ,第二个参数是一个string对象。getline从给定的输入流中读入内容,直到遇到换行符未知,此时换行符也被读入,然后把所读的内容存入到string对象中,此时不存换行符。getline只要一遇到换行符就结束读取操作并返回结果。如果读入的字符串中有空白格,最终也会被输出。
(3)s.empty( ) 和s.size( )
empty是string的一个成员函数,使用点操作符就可以执行函数,如果字符串为空返回true,不为空返回false。 if(!line.empty())
size也是string的一个成员函数,用于输出string对象的长度。如果字符串被初始化时里面有空格会被记录在长度里;如果字符串默认初始化为空,后来手动输入一个字符串,且里面有空格的话,这个空格不被记录在长度里。
s.size( ) 的返回值是一个string::size_type类型的值,他是一个无符号类型的值,返回无符号整数型unsigned,能够存下任何string对象的大小。如果一条语句已经有了size函数就不要再使用int了,可以避免int 和unsigned 同时存在可能带来的问题。
(4)比较string对象
string会逐一比较对象中的字符,同一个字母的大写和小写是不一样滴。== 和 != 为检测两个对象相等与否。还有< 、<=、 >、 >=。
如果a,b两个字符串长度不同,较短的a的每个字符都与较长的b的对象对应位置上的字符一致,则a<b
如果a,b两个字符串再某些对应的位置不一致,则比较第一对相异字符。eg: hello < hiya i比e大。
(5)为string对象赋值
对于string类而言,允许把一个对象的值赋给另一个对象。 string st1="asasa" , st2; st1= st2 ;
(6)两个string对象相加,字面值和string对象相加
两个string对象相加 string s3=s1+s2;
字面值和string对象相加,必须取保每个加法运算符的两侧至少有一个是string对象。
string s6= s1+" hahaha "+s2;
string s7= s3+" dsdsds "+"aaaaaa"; s1+"dsdsds"的结果是一个string对象。
3.处理string对象中的字符
两个常用的cctype头文件中的函数。cctype头文件定义的一组标准库函数能够改变某个字符的特性。
ispunct(c) 当c是标点符号时为真
toupper(c) 如果c时小写字母,则输出对应的大写字母,否则原样输出c
(1)对字符串中每个字符操作
使用范围for语句,遍历每个元素。eg: string str="pikaqiu" ; for (auto c : str) cout<<c<<endl;
(2)改变字符串中的每个字符
使用范围for语句,不过循环变量要定义成引用类型。 for(auto &c : str) cout<< c<<endl;
(3)只处理字符串中一部分字符
有两种方式:使用下标和迭代器。
下标接受的输入参数是string::size_type 类型的值,从0开始记起。
下标必须大于等于0而小于s.size(),所以s[s.size()-1]是最后一个字符。
下标的值称为索引。
在访问指定的字符以前,首先检查是否为空。
对于下标的定义: decltype( s.size() ) index=0;
标准库类型vector
vector表示对象的集合,其中所有对象的类型都相同。
要使用vector,必须包含头文件: #include<vector> using std::vector
vector是模板而非类型,由vector生成的类型必须包含vector中元素的类型,比如vector<int>
1.定义和初始化
vector<T> v1 ; V1是一个空vector,他潜在的元素是T型的,执行默认初始化;
vector<T> v2={a,b,c,.......,} ; v2包含了初始值的元素,每个元素被赋予相应的初始值;
vector<T> v3(n,val); v3包含了N个重复的元素,每个元素的值都是val,如果没有写val,则执行默认初始化。
最常见的方式时先定义一个空vector,然后当运行时获取到元素的值后再逐一往里面添加。
允许把一个vector对象的元素拷贝到另一个vector对象。需要注意的是两个vector对象的类型必须相同。
如果vector对象的元素是内置类型,比如int,则初始化为0;如果为string类型,则初始化为空字符串。
vector<int> v1(10,1); v1有十个值,每个值为1
vector<int> v2{10,1}; v2有两个值,10和1
vector<int> v3(10); v3有十个值,执行默认初始化,每个值都是0
vector<string> v4{10}; v4有十个默认初始化的元素,都为空字符串
2.vector支持的操作
(1)向vector对象中添加元素
最常见的定义方式是先定义一个空vector然后再往里添加。
添加元素应用的是vector的成员函数s.push_back(i)。此函数依次把获取到的值i添加到vector对象的尾端。
(2)其他
v.empty()和v.size()其操作和string类型一样。
v.size()的返回类型也是size_type类型。如果要定义的话 vector<int>::size_type
(3)使用范围for语句,和string用法一样
(4)对象的索引
vector使用下标运算符来获取指定的元素,下标也是从0开始,类型是size_type。
如果s是一个空vector,里面不包含任何元素,那么就不能通过下标去访问。
vector对象以及string对象的下标运算符可以用于访问已经存在的元素,而不能用于添加元素。
迭代器(访问单个元素或字符,和下标运算符类似)
所有的标准库容器都可以使用迭代器,但只有少数支持下标运算,所以迭代器更为通用。
1.使用迭代器
类似于指针,迭代器提供了对对象的间接访问;和指针不同的是,获取迭代器不使用取地址符,而是用成员函数begin()和end()。
s.begin()负责返回指向第一个元素或字符的迭代器;s.end()负责返回指向对象尾元素的下一位置的迭代器,也就是说指向一个不存在的尾端。无意义,只是表示处理完了容器中所有的元素而已。end成员返回的迭代器通常称为尾后迭代器。
如果容器为空,则begin和end返回的都是同一个迭代器,都是尾迭代器。
2.标准容器迭代器的运算符
*iter 返回迭代器iter所指元素的引用
下面代码实现了把对象的第一个字母变为大写。
string s="abcde"; if(s.begin()!=s.end()) autoit=s.begin();*it=toupper(*it);
首先要判断s是否为空;it表示s的第一个字符,使用auto类型;最后解引用变化字母。
3.移动元素
++iter --iter令iter指向容器中的下一个元素/上一个元素(移动了一个位置)
4.迭代器类型
一般来说不知道迭代器的类型,而实际上拥有迭代器的标准库类型使用iterator和const_iterator来表示迭代器类型。
前者能读写元素,后者只能读不能写元素。
每个容器类定义了一个名为iterator的类型,该类型支持迭代器概念上所规定的一套操作。
begin和end返回的具体类型由对象是否为常量决定。如果对象是常量,则返回const_iterator,否则返回iterator类型。
为了便于得到const_iterator类型的返回值,C++11引入了两个新函数cbegin和cend。无论vector或string本身是否为常量,返回值都是const_iterator。
5.结合解引用和成员访问操作
箭头运算符把解引用和成员访问两个操作结合起来,it->empty()等同于(*it).empty()。
依次输入s的每一行直至遇到第一个空白为止:
for(auto it=s.cbegin();it!=s.cend() &&it->empty();++it) cout<<*it<<endl;
因为循环从头至尾只是读取s的元素而未向其中写值,所以用cbegin和cend来控制。
6.迭代器运算
vector和string迭代器支持的运算
(1)iter+n iter-n
令迭代器和一个整数值相加或相减,其返回值是向前或向后移动了若干个位置的迭代器。
(2)iter1 -iter2(无加法运算)
只要两个迭代器指向的是同一个容器中的元素或尾元素的下一位置,就可以相减,其结果是两个迭代器的距离。
所谓距离是右侧迭代器向前移动多少位置就能追上左侧迭代器,类型名为difference_type的带符号整型数,所以这个距离可正可负。
(3)关系运算符 >,>=,<,<=
数组
类似于vector。相同点是数组也是存放类型相同的对象的容器;不同点是,数组的大小确定不变,不能随意向数组中添加元素。
如果不清楚元素的确切个数,还是用vector。
1.定义和初始化
unsigned a=12; constexpr unsigned b=12;
string c[a]; 错误 string d[b]; 正确 维度必须为一个常量表达式
显示初始化:
int a[ ] ={0,1,2,3}; 如果声明没有指定维度,编译器会根据初始值的数量计算并推导出来
int b[ 5 ] ={0,1,2 }; 如果维度比提供的初始值数量大,则用提供的初始值初始化靠前的元素,剩下的元素被初始化成默认值(0或者空字符串)
值得注意的是:用字符串字面值去初始化数组时,字符串结尾的空字符也会占一个空间。所以存储字符串“abc” 需要的数组是a[4] 而非a[3];
不能将数组的内容拷贝给其他数组作为初始值,也不能用数组为其他数组赋值。
数组本身就是对象,所以运行定义数组的指针和数组的引用。
数组的指针:int (*parray)[10]=&arr; parray是一个指针,它指向int型数组,数组中包含10个元素。
数组的引用:int (&parray)[10]= arr; parray是一个引用,它应用的对象是一个大小为10的数组,数组中元素的类型是int。
想要理解数组声明的含义,可以按照由内而外的顺序阅读。
2.访问数组元素
在使用数组下标的时候,通常定义成size_t类型,无符号类型,被设计的足够大能表示内存中任意对象的大小。在cstddef头文件中定义了这种类型。
数组下标的定义:constexpr size_t sz=5;
数组除了大小固定以外,其他用法都与vector基本类似。需要遍历所有元素时可以用for语句。注意防止下标越界。
3.指针和数组
数组的元素也是对象,对数组的元素使用取地址符就能得到指向该元素的指针。string *p = &nums[0] ;p指向nums的第一个元素。
在很多用到数组名字的地方,编译器都会自动将其替换为指向数组首元素的指针: string *p=nums; 等价于 p=&nums[0];
在大多数表达式中,使用数组类型的对象其实是使用一个指向该数组首元素的指针。数组的操作实际上是指针的操作。
指针也是迭代器。vector和string的迭代器支持的运算,数组全部支持。
4.标准库函数begin()和end()
这两个函数与容器的两个成员功能类似,不过数组不是类类型,所以这两个函数不是成员函数,正确的形式是将数组作为它们的参数。
int ia[ ] = {0,1,2,3,4,5,6}; int *beg=begin(ia); 指向ia首元素的指针 int *last=end(ia);指向ia尾元素的下一位置的指针。这两个文件定义在iterator头文件中。
特别注意尾后指针不能执行解引用和递增操作。
5.指针运算
给一个指针加上或减去某整数值,结果仍是指针。新指针比原指针前进或后退了某整数个位置。
两个指针相减的结果是带符号型的名为ptrdiff_t的类型。定义在头文件cstddef中。
内置的下标运算符所用的索引值不是无符号类型的,可以为负值,这一点与string和vectror不同。
8.C风格字符串的函数
strcmp(p1,p2);比较p1 p2的相等,相等返回0 ,P1>P2返回一个正值,P1<P2返回一个负值。
strcat(p1,p2); 将P2附加到P1之后,返回P1。
strcpy(p1,p2); 将P2拷贝给P1。返回P1。
9.多维数组
C++所说的多维数组其实是数组的数组。
使用范围for语句处理多维数组,除了最内层的循环外,其他所有循环的控制变量都应该是引用类型。
- Object C NSArray (学习笔记三)
- 《C和指针》学习笔记(三)
- c++primer学习笔记(三)
- c++Templates学习笔记(三)
- [C++]C++学习笔记(三)
- C语言程序学习(三)笔记
- 《Effective C++》学习笔记(三)
- C/C++学习笔记(三)
- Objective-c 学习笔记(三)
- C语言学习笔记(三)
- 学习C的一些笔记(三)
- C/C++学习笔记三(函数)
- 《effective c++》学习笔记(三)
- c语言学习笔记三
- C语言学习笔记<三 >
- C/C++学习笔记(三)
- C++Primer学习笔记《三》
- Objective C学习笔记(三)
- mysql5.6安装配置过程(免安装版)-win7(64位)
- 微信支付扫码支付
- 【NOIP2016提高A组集训第10场11.8】时空传送
- [noip2015pj] 扫雷游戏
- java基础知识之Java程序初始化顺序
- C++学习笔记(三)
- ETL是什么?
- graphics 架构
- C++之继承关系总结
- 选择排序(SelectSort)
- JSON
- Linux学习37_LINUX下设置网卡开机自启动
- Android 实现心电图
- ES6-let篇