一、介绍
内置类型
类似于标准库vector
,也是存放类型相同对象的顺序容器。
不同的地方:数组的大小确定不变,不能随意向数组中增加元素,不够灵活。
注意:如果不清楚元素的确切个数,请使用vector
二、定义和初始化内置数组
声明形如 a[d]
,其中a
是数组的名字,d
是数组的维度。
维度说明了数组中元素的个数,因此必须大于0。
维度必须是一个常量表达式。
unsigned cnt = 42; // 不是常量表达式
constexpr unsigned sz = 42; // 常量表达式
int arr[10]; // 含有10个整数的数组
int *parr[sz]; // 含有42个整型指针的数组
string bad[cnt]; // 错误:cnt不是常量表达式
string strs[get_size()]; // 当get_size()是常量表达式时正确, 否则错误
显式初始化数组元素
const unsigned sz = 3;
int ial[sz] = {0, 1, 2}; // 含有3个元素的数组,元素值分别是 0, 1, 2
int a2[] = {0, 1, 2}; // 维度是3的数组
int a3[5] = {0, 1, 2}; // 等价于 a3[] = {0, 1, 2, 0, 0}
string a4[3] = {"hi", "bye"}; // 等价于 a4[] = {"hi", "bye", ""}
不允许拷贝和赋值
不能将数组的内容拷贝给其他数组作为其初始值,也不能用数组为其他数组赋值:
int a[] = {0, 1, 2}; // 含有3个整数的数组
int a2[] = a; // 错误: 不允许使用一个数组初始化另一个数组
a2 = a; // 错误: 不能把一个数组直接赋值给另一个数组
三、访问数组元素
类似于string
和 vector
,数组的元素也能使用范围for
语句或下标运算符来访问。
在使用数组下标的时候,通常将其定义为size_t
类型。size_t
是一种机器相关的无符号类型,它被设计得足够大以便能够表示在内存中任意对象的大小。
在cstddef
头文件中定义了size_t
类型,这个文件是C标准库stddef.h
头文件的C++语言版本。
unsigned scores[11] = {}; // 11 个分数段,全部初始化为0
for (auto score : scores) {
cout << i << " "; // 输出当前的计数值
}
四、指针与数组
使用数组的时候,编译器一般会把它转换成指针。
通常情况下,使用取地址符&
来获取指向某个对象的指针。
在很多用到数组名字的地方,编译器都会自动地将其替换为一个指向数组首元素的指针:
string nums[] = {"one", "two", "three"};
string *p2 = nums; // 等价于p2 = &nums[0]
使用指针遍历数组元素
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *e = &arr[10]; // 指向arr尾元素的下一位置的指针
// 注意:指针也是迭代器
for (int *b = arr; b != e; ++b) {
cout << *b << endl; // 输出arr的元素
}
标准库函数begin
和end
int ia[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *beg = begin(ia); // 指向ia首元素的指针
int *last = end(ia); // 指向arr尾元素的下一位置的指针
begin
和end
这两个函数定义在iterator
头文件中
特别注意:尾后指针不能执行解引用和递增操作。