前言:初学C++,就觉得C略显原始,最近看《C++ Primer》了解了一点类型,在这里做个笔记
数组
C++中的数组与C中的数组区别不大,数组名字代表了首元素的地址,声明一个数组的维度使用常量表达式:int array[10];
也可以int array[] = {1, 2, 3};
若是没有显示初始化,则会被初始化为默认值。
访问的时候有两种方式:int a = array[1];
,也可以int a = *(array + 1);
这与C中是一样的,无需多言。
C++11中引入了两个函数begin()
和end()
,定义于<iterator>
头文件中,以数组名为参数时分别返回该数组的首元素指针和尾元素下一个位置的指针,通过这两个指针我们便可以通过for
遍历每个元素,当然,也可以使用for (auto &i : array)
遍历。
值得一提的是,数组作为对象也存在引用与指针,如:int (*arr1)[10] = &array;
和int (&arr2)[10] = array;
分别代表指向array的指针和对array的引用。
由于数组的大小固定,所以比之vector灵活性更差,而数组类型的C字符串也不如string方便。至于多维数组,其性质与C中并无明显差别,也就不提。
vector
标准库类型vector表示对象的集合,与数组相似,但不限长度,被称为容器,是一个类模板,而要使用vector,必须包含<vector>
头文件,且定义于命名空间std中
vector能容纳绝大多数类型的对象为元素(不包括不是对象的引用),同时作为一个对象,vector同样能作为对象被容纳。
定义和初始化
vector<int> v1; //默认初始化
vector<int> v2(v1); //v2包含v1元素的副本
vector<int> v3 = v1;
vector<int> v4(n, val)//包含n个重复的val
vector<int> v5(n)//包含n个默认初始化的元素
vector<int> v6{1, 2, 3};//列表初始化
vector<int> v7 = {1, 2, 3};
以上为vector的初始化方法,不同于数组,vector可以使用=
直接将一个同类型的vector赋值给另一个
运算
vector支持不同的操作,在此列出部分:
v.empty() //若v为空返回真
v.size() //返回元素个数
v.push_back(t) //向尾段添加一个值为t的元素
//而不能通过下标直接添加
v[n] //返回第n个元素的引用
v1 = v2
v1 = {a, b, c}
v1 == v2 //v1和v2相等当且仅当元素数量相同且
//对应位置元素相同
v1 != v2
v1 < v2 //以字典顺序进行比较,也有<=,>,>=
三个函数为vector的成员函数,其中v.size()
返回由vector定义的size_type
类型
与数组相同,可以使用下标访问vector中的元素,且只能访问已存在的元素
数组与vector
C++不允许用vector为数组赋初值,但却允许用数组为vector赋初值,只需指明首元素地址和尾后地址即可
int arr[] = {1, 2, 3}
vector<int> ivec(begin(arr), end(arr));
string
标准库类型string表示可变长的字符序列,与vector类似,拥有自己的头文件<string>
且定义于命名空间std中
定义初始化
string s1;
string s2(s1);
string s3 = s1;
string s4("value");//直接初始化
string s5 = "value";//拷贝初始化
string s6(n, 'c');
与vector类似的定义初始化方法,这里不做注释
运算
os << s //将s写到输出流os中,返回os
is >> s //从is中读取字符串赋给s,以空白分隔,返回is
getline(is, s) //从is中读取一行赋给s,返回is
s.empty()
s.size() //返回字符个数
s[n] //返回第n个字符的引用
s1 + s2 //返回s1和s2连接后的结果
s1 = s2
s1 == s2 //对大小写敏感的相等性判断
s1 != s2
s1 > s2 //字典顺序比较,另有>,>=,<
当从输入流中读写s时,会自动忽略开头的空白,而在下一处空白时结束,而若要读取空白,可以使用getline()
读取一整行
与vector类似,s.size()
返回string中定义的类型size_type
相加时,只需保证+
两边至少有一个string类型即可,值得一提的是,字符串字面值并不属于string
处理字符
在<cctype>
头文件中包含了一组标准库函数处理字符(对应C中的<ctype.h>
头文件),此处不列出
在处理每个字符时,同样可以使用范围for语句进行遍历
而使用下标访问时,必须注意索引范围在区间[0,s.size() - 1]
C风格字符串与string
C++支持C风格字符串,<cstring>
是<string.h>
的C++语言版本
C++允许使用以空字符结束的字符数组初始化string对象或为其赋值,而如果要把string类型的对象赋给C字符串,则需要使用string成员函数c_str()
,返回指向空字符结束的字符数组的指针,内容与string一样,且类型为const char*
但实际使用过程中,string无疑更方便
迭代器
迭代器是一种比下标访问更通用的机制,所有标准库容器都支持迭代器
使用迭代器
有迭代器的类型同时拥有返回迭代器的成员,比如begin()
和end()
,分别返回指向首元素的迭代器和尾后迭代器
迭代器支持运算,如
*iter //返回所指元素的引用
iter -> mem //解引用iter并获取mem成员,相当于 (*iter).mem
++iter
--iter
iter1 == iter2
iter1 != iter2
因为end()
返回的迭代器不指示某个元素,所以不能递增和解引用
迭代器类型
标准库类型使用iterator
和const_iterator
表示迭代器的类型,可以使用auto
和decltype
忽略类型地声明一个迭代器
begin()
和end()
返回类型由对象决定是否为常量,C++11引入了cbegin()
和cend()
两种必然返回const_iterator
的函数
运算
迭代器同样可以使用+
,-
,+=
,-=
等运算符,也可以相互根据指向位置前后进行比较,相减则就可以得到两个同一容器迭代器之间的距离,距离返回difference_type
类型的带符号整数
其他
注意,当容器容量改变时,原有迭代器都会失效,如向vector中添加元素。
个人认为,若容器支持下标运算,则下标运算会更方便,但迭代器无疑更普遍,深入学习后或许便能发现其比下标更优的地方
以上,便是本人这学期初的瞎学成果,课上还学习了class
,此处不作详细记录。