- using声明语法:using namespace::name;如,using std:cin;
- 头文件不应该包括using声明
- 初始化string对象的方式:
- string s1;//默认初始化,s1是个空串
- string s2(s1);//s2是s1的副本
- string s2 = s1;//等价于s2(s1),s2是s1的副本
-
string s4(n,’c’)//把s4初始化为由连续n个字符c组成的串
ps:2、4为直接初始化(没用=),3为拷贝初始化(用了=),4可转换为拷贝初始化:string s4 = string(n,’c’);
- string的基本操作
- os << s;
- is >> s;
- getline(is, s);//从is中读一行赋给s,返回is
- s.empty();s为空,返回true
- s.size();返回s中字符的个数
- s1+s2;返回s1 s2的连接
- s1==s2;
- s1!=s2;
- s1>=s2;(> <= <)//字典序比较
- size()函数返回值类型为string::size_type类型,size_type是无符号的,Tips:如果一条表达式中已经有size()函数了,就不要再用int了,这样可以避免混用int和unsigned可能带来的问题
-
字符串+操作:不能将字面值与字面值直接相加
tips:C++语言中的字符串字面值并不是标准库类型string的对象。切记:字符串字面值与string是不同的类型
- cctype头文件中的函数
- isalnum(c);当c是字母或数字时为真
- isdight(c);当c是数字时为真
- isxdight(c);当c是16进制数字时为真
- isalpha(c);当c是字母时为真
- islower(c);当c是小写字母时为真
- isupper(c);当c是大写字母时为真
- iscntrl(c);当c是控制字符时为真
- isgraph(c);当c 可打印但不是空格时为真
- isprint(c);当c是可打印字符时为真(c具有可视形式或c是空格)
- isspace(c);当c是空白时为真(即c是空格、横向制表符、数字、字母、可打印空白中的一种)
- ispunct(c);当c是标点符号时为真(即c不是控制字符、数字、字母、可打印空白中的一种)
- tolower;转换为小写字母
- toupper;转换为大写字母
-
Tips:建议使用C++版本的C标准库头文件。
C++标准库中除了定义C++语言特有功能外,也兼容了C语言的标准库,只不过将名字由name.h转变为cname。一般使用cname形式的头文件
- string中单个字符类型为char
-
要想访问string对象中的单个字符有两种方式,一种是使用下标,一种是使用迭代器。
下标运算符[],下标的值成为下标或索引
- C++语言既有类模板,又有函数模板,其中vector是一个类模板。模板本身不是类和函数。编译器根据模板创建类或函数的过程称为实例化。
-
对于类模板,我们提供一些额外信息来制定模板到底实例化乘什么样的类,需要提供哪些信息由模板决定。
提供信息的方式总是这样:即在模板名字后面加一个尖括号,在括号内放上信息。
以vector为例,提供的额外信息是vector内所存放对象的类型,如:vector< int> ivec;
- 初始化vector对象的方法
- vector< T> v1//v1是一个空vector,执行默认初始化
- vector< T> v2(v1)//v2中包含所以v1元素的副本
- vector< T> v2 = v1//等价于v2(v1)
- vector< T> v3(n, val)//v3包含了n个值val的元素
- vector< T> v4(n)//v4包含了n个默认初始化的元素
- vector< T> v5{a,b,c,d…}//v5包含的每个元素被赋予特定值。PS:一定注意是花括号!!!
- vector< T> v5 = {a,b,c,d…}//等价于v5{a,b,c,d…}
- 特例:vector< string> v7{10};vector< string> v7{10,”hi”}都是正确的
- vector支持的操作
- v.empty()如果v为空,返回true
- v.size返回v中元素的个数
- v.push_back(t)向v的尾端添加一个值为t的元素
- v[n]下标访问
- v1 == v2 v1 != v2
- < <= > >=
- 不能以下表的形式添加元素。只能对已存在的元素执行下表操作,试图用下标访问一个不存在的元素将引发错误,会导致错误,如buffer overflow(缓冲区溢出)
-
迭代器——访问string vector的另一种途径。
标准库容器都支持迭代器,只有其中的几种支持下标访问。
类似于指针,迭代器也实现了元素的间接访问
严格来说,string类型不属于容器类型,但是string支持很多与容器类似的操作。
-
v.begin() 返回指向第一个元素的迭代器
v.end() 返回指向容器“尾元素的下一位置”的迭代器,被称作尾后迭代器,尾迭代器。没有实际含义,只作为一个标记
如果容器为空,则begin() end()返回的是同一个迭代器,都是尾后迭代器
- 标准容器迭代器的运算符
- *iter 返回迭代器iter所指元素的引用
- iter->men 解引用iter并获取钙元素的名为men的成员,等价于(*iter).men
- ++iter 令iter指示容器中的下一个元素
- –iter 上一个元素
- iter1 == iter2(iter1 != iter2) 判断是否相等
-
概念:泛型编程
所有标准库容器都定义了==和!=,但它们中的大多数都没有定义<运算符。养成用迭代器和!=的习惯,就不用太在意用的到底是哪种容器了。
- 迭代器类型:iterator和const_iterator(只读不能写)
- vector对象可以动态增长,但也带来了副作用。
- 不能在范围for循环中向vector对象添加元素。
-
任何一种可能改变vector对象容量的操作,比如push_back,都会使该对象的迭代器失效
Tips:凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加元素。
- vector 和 string支持的迭代器运算
- iter+n(iter-n)
- iter1-iter2 返回它们之间的距离,类型为difference_type的带符号整形数
- > >= < <= 迭代器的关系运算器,若在前面则小于
- 数组。和vector相比,相同点:也是存放类型相同的对象的容器,这些对象本身没有名字,需要通过其所在位置访问。不同点:数组大小固定不变,不能随意向数组中增加元素。某些场合运行时效率较好,但失去了灵活性。
- 定义和初始化内置数组
-
定义:数组的维度必须是一个常量表达式。如下面是正确的:
constexpr int sz = 42;
string strs[sz];
-
显示初始化数组元素
int a2[] = {0, 1, 2};//维度是3
int a3[5] = {0, 1, 2};//初始化了前3个元素
int a5[2] = {0, 1, 2};//错误!初始值错误
-
字符数组的特殊性
字符数组有一种额外的初始化形式,即可以用字符串字面值对此类数组初始化。但注意!字符串字面值的结尾处还有一个空字符,这个空字符也会像其他字符一样,被拷贝到字符数组里。
char a1[] = {‘C’, ‘+’, ‘+’};//无空字符,维度为3
char a2[] = {‘C’, ‘+’, ‘+’, ‘\0’};//有空字符,维度为4
char a3[] = “C++”;//自动添加空字符,等同于上一句
char a4[6] = “Daniel”;//错误:没有空间可存放空字符
- 不允许拷贝和赋值:不允许用一个数组初始化另一个数组,不能把一个数组直接赋值给另一个数组
-
理解复杂的数组声明:
int *ptrs[10];
int &refs[10] = ;//错误,不存在引用的数组
int (*Parray)[10] = &arr;//Parray指向一个含有10个整数的数组
int (&arrRef)[10] = arr;//arrRef引用一个含有10个整数的数组
-
- 数组下标通常定义为size_t类型。它在cstddef头文件中定义
- 指针和数组
-
使用数组类型的对象其实是使用该数组首元素的指针,
string nums[] = {“one”, “two”, “three”};
string *p = &nums[0];//p指向nums的第一个元素
string *p2 = nums;//等价于p2 = &nums[]0; 即 nums == &nums[0]
auto nums2(nums);//nums2是一个指针,等同于p p2
- 指针的运算 p1-p2 p1==p2 (!= > >= < <=)
-
指针的下标运算
int *p = &ia[2];
int j = p[1];//p[1] == *(p+1)
int k = p[-2];//p[-2] == *(p-2)
-
-
C风格字符串:字符串字面值:最后一个字符后面跟着一个空字符(’\0’)
C标准库String函数(定义在cstring头文件中,注意区别于string头文件)
- strlen(p) 返回p的长度
- strcmp(p1, p2) p1==p2返回0 p1>p2返回正值 p1< p2返回负值
- strcat(p1, p2) 将p2附加到p1之后,返回p1
-
strcpy(p1, p2) 将p2拷贝给p1,返回p1
注意:传入此类函数的指针必须指向以空字符作为结束符的数组:如:
char ca[] = {“C”, “+”, “+”};
cout << strlen(ca) << endl;//严重错误:ca没有以’\0’结束
- 多维数组:严格来说,C++没有多维数组,通常多维数组其实是数组的数组。谨记!!
-
多维数组的初始化
int ia[3][4] = { {0,1,2,3}, {4,5,6,7}, {8,9,10,11} };
int ia[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};//等同于上句
int ia[3][4] = { {0}, {4}, {8} };//初始化首列,其余元素执行默认值初始化
int ia[3][4] = {0,3,6,9};//初始化首行,其余元素执行默认值初始化