array的长度是静态的,即在编译阶段就已经确定。没有 vector 灵活,但性能一般更强。
1. 声明
维数必须是一个 constant expression,另外数组中每个单元必须指明类型(不能用auto),必须是对象,不能是别名(reference)。
1 int arr[10]; 2 int *parr[sz]; // 42 个整数指针 3 string str[ get_size() ]; // 如果 get_size() 返还常数表达式就ok,否则错误
2. 初始化
int ia1[3] = {0,1,2}; int ia1[] = {0,1,2}; // 自动确定维数为3 int ia1[5] = {0,1,2}; // 自动将后2个元素初始化为0 string a4[3] = {"hi", "bye"}; //自动将最后一个元素初始化为""
3. 字符数组
字符数组多一个隐含的元素 在末尾,作为结束的标志。
char a1[] = {'C', '+', '+'};//长度实际为4,自动增加 ' ' char a4[6] = "Daniel"; //错误,没有空间给隐含的 ' '
4. 指向数组的指针
int * ptrs[10]; // ptrs 是10个整数指针构成的数组 int (*Parray) [10] = & arr; // Parray 是指向数组arr 的指针,arr由10个整型构成 int (&arrRef) [10] = arr; // arrRef 是数组 arr 的别名,arr 由10个整型构成 int * (&arry) [10] = ptrs; // ptrs 是 10 个指向整型的指针构成的数组,arry 是它的别名
5. 引用数组的单元
可以用下标,也可以用 range for。下标范围是 0, 1, n-1,其中n为维数。下标应为 size_t 类型,size_t 无符号,可以足够大,在 cstddef 头文件中。
如果要遍历所有单元,用 range for 是更好的选择,
unsigned scores[11] = {}; for( auto i: scores) cout<< i << " "; cout<<endl;
6. 指针与数组
实际上,数组就是用指针实现的。
string num[] = {"one", "two", "three"};// num 也是一个指针,指向第一个元素
7. begin, end 函数
指针是一种迭代器,但数组不是类,所以没有成员函数 begin(), end(),于是 library 提供了 begin(arr), end(arr) 函数
int *pbeg = begin(arr), *pend = end(arr); while( pbeg != pend && *pbeg >=0) // 寻找整数数组中第一个负整数 ++pbeg;
不可以dereference 或者增加 end(arr)指针,因为 end(arr) 指向的是数组外的地址。
因为指针是迭代器,所以其他迭代器的操作也适用,比如加上一个整数(若指向数组外,除了end(arr)以外的值是错误的),两个指针相减,比大小。
下标符号[] 可以用在任何指针上,只要得到的元素再数组内。
int ia[] = {0,2,4,6,8}; int *p = & ia[2]; // p 指向元素4 int k = p[-2]; // k = ia[0] = 0
所以下标可以是负整数,只要得到的元素仍在数组内就行。
8. C风格的字符串
我记得谭浩强老师的C++教程就是沿用的C风格的字符串,它是如下表示的:
char a[80] = "hahaha"; // 自动用' '结束,即 a[6]=' '
默认用 ' ' 表示字符串内容的结束,数组长度必须大于等于字符串长度+1。
library提供了一些函数对这种风格的字符串进行操作
strlen(p) 字符串p的长度,不包括'