数组

数组

固定长度,如果要改变数组的长度,只能创建一个更大的数组,然后将老数组的数据复制过去。所以,现代的C++程序更多地使用 vector 来取代数组。

数组的定义和初始化

数组的维数只能通过常量表达式来定义,只能包含:整型字面常量、枚举常量、用常量表达式初始化的整形 const 对象非 const 变量以及要到运行阶段才知道其值的 const 变量不能 定义数组的维数。由于数组里面的元素都是对象,所以也不存在引用的数组。例如以下这种是不能定义数组的。

1
2
int size = 6;
int array[size]; //要报错。如果是const int的话就不会报错了

注:在函数体外面定义的内置数组,如果没有显式的提供初值,则其中所有元素会被初始化为0;在函数体内部定义的内置数组不会被初始化。

注2:不能用 auto 关键字来推断数组的数据类型

注3:不能将数组的内容拷贝给其他数组,也不能用数组为其他数组赋值,错例如下

1
2
3
int a[] = {0, 1, 2};
int a2[] = a; //错的,不能用一个数组初始化另一个数组
a2 = a; //错的,不能用数组直接赋值给另一个数组

字符数组的两种初始化形式和他们的区别

1
2
char char_array[] = {'C', '+', '+'}; //只有3个元素
char char_array2[] = "C++"; //有4个元素,最后隐含了一个‘\0’

数组操作

数组里面下标的类型是 size_t,这是在头文件中定义的及其相关的无符号整型,该类型足以保存最大数组的长度。

标准库函数 begin 和 end

为了减少指针使用的困难,头文件中定义了 begin() 和 end() 两个函数。这两个函数和容器里的成员功能一样。如

1
2
3
int ia[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *beg = begin(ia); //指向ia首元素的指针
int *last = end(ia); //指向ia尾元素的下一位置的指针

指针和多维数组

1
2
3
4
5
6
7
int ia[3][4] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};
int (*p)[4] = ia; //去掉圆括号就是整型指针的数组
//C++11允许用auto或者decltype来避免定义像p这种指针的困难情况了
for(auto p = ia; p != ia + 3; ++p) //p指向ia[0]的四个元素的数组
for(auto q = *p; q != p + 4; ++q) //q指向ia[0][0]
cout << *q << '';
cout << endl;

第二行采用从内向外的方式理解:(*p) 代表这是一个指针,[4] 表示这个指针指向的是一个有 4 个元素的数组,int 说的是这个数组是整型。

使用标准库 begin 和 end 的版本如下

1
2
3
4
5
for(auto p = begin(ia); p != end(ia); ++p)
{
for(auto q = begin(*p); q != end(*p); ++q)
cout << *q <<endl;
}