一、前言
介绍使用数组的基本方法,同时介绍C++中string的初始化和一些常用函数。
数组
数组与vector相似的地方是,数组也是存放类型相同的对象的容器,这些对象本身没有名字需要通过其所在位置访问。与vector不同的是,数组的大小确定不变,不能随意向数组中增加元素。因为数组的大小固定,因此对某些特殊的应用来说程序运行时性能较好,但是相对地也损失了一些灵活性。
note: 如果不清楚元素的确切个数,请使用vector。
定义和初始化内置数组
数组是一种复合类型,数组中元素的个数也属于数组类型的一部分,编译的时候维度应该是已知的。也就是说,维度必须是一个常量表达式。
|
|
默认情况下,数组的元素被默认初始化。另外数组的元素应为对象,因此不存在引用的数组。
显式初始化数组元素
可以对数组的元素进行列表初始化,此时允许忽略数组的纬度。
|
|
字符数组的特殊性(用字符串字面值对数组进行初始化)
字符数组可以用字符串字面值初始化,但是特殊的是结束符(’\0’)也会被拷贝进去
a4数组的大小必须至少是7。
数组不允许拷贝和赋值
不能将数组的内容拷贝给其他数组作为其初始值,也不能用数组为其他数组赋值:
|
|
理解复杂的数组声明
可以定义一个存放指针的数组。又因为数组本身是对象,所以允许定义数组的指针(指向数组的指针)及数组的引用(对数组的引用)。
|
|
默认情况下,类型修饰符从右向左一次绑定, 对于ptrs来说,首先知道我们定义了一个大小为10的数组,它的名字是ptrs,然后知道数组中存放的是指向int的指针。
要想理解数组声明的含义,最好的办法是从数组的名字开始按照由内向外的顺序阅读。
Parray的含义:首先*Parray意味着Parray是个指针,接下来观察右边,可知道Parray是个指向大小为10的数组的指针,最后观察左边,知道数组中的元素是int。最终,Parray是一个指针,它指向一个int数组,数组中包含10个元素。
当然,对修饰符的数量并没有特殊限制:
|
|
访问数组元素
数组的元素也能使用范围for语句或下标运算符来访问。
当需要遍历数组的所有元素时,最好的办法也是使用范围for语句。
|
|
指针和数组
在C++语言中,指针和数组有非常紧密的联系。使用数组的时候编译器一般会把它转换成指针。
|
|
数组的一个特性:在很多用到数组名字的地方,编译器都会自动地将其替换为一个指向数组首元素的指针。
|
|
auto 和 decltype
|
|
指针也是迭代器
|
|
遍历数组元素,我们可以设法获取数组尾元素之后的那个并不存在的元素的地址:
|
|
note: 尽管能计算得到尾后指针,但是这种用法极易出错,C++11新标准引入了两个名为begin和end的函数。这两个函数与容器中的两个同名成员功能类似。
begin函数返回指向ia首元素的指针,end函数返回指向ia尾元素下一位置的指针,这两个函数定义在iterator头文件中。
正确的使用形式:
note: 一个指针如果指向了某种内置类型数组的尾元素的”下一位置“,则其具备与vector的end()函数返回的与迭代器类似的功能。特别要注意,尾后指针不能执行解引用和递增操作。
下标和指针
|
|
注意: 内置的下标运算符所用的索引值不是无符号类型,这一点与vector和string不一样。
C风格字符串
C风格字符串不是一种类型,而是为了表达和使用字符串而形成的一种约定俗成的写法。按此习惯书写的字符串存放在字符数组中并以空字符结束(null terminated)。以空字符结束的意思是在字符串最后一个字符后面跟着一个空字符(’\0’)。
C风格字符字符串函数
|
|
对大多数应用来说,使用标准库string要比使用C风格字符串更安全、更高效。
与旧代码的接口
现代的C++ 程序不得不与那些充满了数组或C风格字符串的代码衔接,为了使这一工作简单易行,C++专门提供了一组功能。
混用string对象和C风格字符串
允许使用字符串字面值来初始化对象:
|
|
更一般的情况,任何出现字符串字面值的地方都可以用以空字符结束的字符数组来替代:
- 允许使用空字符结束的字符数组来初始化string对象或为string对象赋值。
- 在string对象的加法运算过程中允许使用以空字符串结束的字符数组作为其中一个运算对象(不能两个运算对象都是);在string对象的复合赋值运算中匀速使用以空字符串结束的字符数组作为右侧的运算对象。
上述性质反过来就不成立,比如不能用string对象直接初始化指向字符的指针。为了完成该功能,string专门提供了一个名为c_str的成员函数。
|
|
我们无法保证c_str()返回的数组一直有效,事实上,如果后续的操作改变了s的值就可能让之前返回的数组失去效果。因此使用最好将c_str()返回的数组拷贝一份。
使用数组初始化vector对象
不允许使用一个数组为另一个内置类型的数组赋初值,也不允许使用vector对象初始化数组。相反的,允许使用数组来初始化vector对象
|
|
注意: 现代的C++程序应当尽量使用vector和迭代器,避免使用内置数组和指针;应该尽量使用string,避免使用C风格的基于数组的字符串。
多维数组(待补充)
string
string表示可变长的字符序列,使用string类型必须首先包含string头文件。
初始化string对象的方式
|
|
string对象上的操作
|
|
代码示例
|
|
处理string对象中的字符
对字符处理的一些方法,在cctype头文件中定义了一组标准库函数处理这部分工作
处理string每个字符,使用基于范围的for语句
|
|
只处理string一部分字符
要想访问string对象总的单个字符有两种方式:一种是使用下标,另外一种是使用迭代器。
注意:检查下标的合法性
一种简便易行的方法是:总是设下标的类型为string::size_type,因为此类型是无符号数,可以确保下标不会小于0,此时,代码只需要保证下标小于size()的值就可以了。
|
|