Arrays
array和vector类似,但是array性能更好,灵活性较差(trade-off between performance and flexibility)。
初始化array
const unsigned sz = 3;
int ia1[sz] = {0,1,2};
int a2[] = {0,1,2};
int a3[5] = {0,1,2};//a3[] = {0,1,2,0,0};
string a4[3] = {"hi","bye"};//a4[] = {"hi","bye",""};
int a5[2] = {0,1,2};//error!
character array
一种和string有些类似的东西,叫做character array,虽然在C++语言中不常见,但有一些特殊用处,如声明的字符串中包含一些特殊字符时。
需要注意的是,character array必须以空字符('/0'))结尾,否则计算机无法知道该字符串终结处,而这个空字符是计入array大小中的(和std::string不同,string.size()是不包含空字符的,事实上std::string是一个类,因此根本就没有空字符!)
char a1[] = {'c','+','+'};//size = 4
char a2[] = {'c','+','+','\0'};//size = 4
char a3[] = "C++";//size = 4
char a4[6] = "Daniel";//error! no space for the null!
no copy or assignment
array不能copy创造,也不能赋值。
int a2[] = a;//error! no copy!
a2 = a;//error! no assignment!
我们知道,array本质是一个指针。然而,和指针的区别是,指针是可修改的左值,但array不是!
复杂的array声明结合了指针(*)和引用(&)后,array的声明会有一些晦涩。
关键在于,从内往外看(inside out)!而不是从右往左看。
int (*parray)[10] = &arr;//parray是一个pointer,points to an array of ten ints
int (&arrRef)[10] = arr;//arrRef是一个reference,refers to an array of ten ints
begin 和 end
C++ 11中为array也提供了begin和end,cbegin和cend函数哦!
int *pbeg = begin(a), *pend = end(a);
for (; pbeg < pend; pbeg++){
cout << *pbeg << endl;
}
Multidimensional Array
初始化一个多维数组
int ia[3][4] = {
{0,1,2,3},
{4,5,6,7},
{8,9,10,11}
};
int ia[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
上面两种初始化方法是等价的,但是第一种显然要清晰得多!
使用"{}",我们显式地把每一行(更准确的说是,每一个子数组)分开了。
int ia[3][4] = {{0},{4},{8}};
int ia[3][4] = {0,3,6,9};
上面第一行表示:前四个都是0,然后四个都是4,然后四个都是8.
上面第二行,只对前四个赋值,剩下8个都是0.
range for 和 multidimensional array
当我们使用range for和multidimensional array时,有一个不容易察觉的致错因素。
<pre name="code" class="cpp">int ia[3][4] = {0};
for(auto row:ia){
for(auto col:row){
...
}
}
上面这段代码看似没问题,我们先遍历ia的每一行,然后遍历ia每一行的每一个元素。但是,这是不能编译通过的!
这是因为,compiler会默认把array转换成pointer,所以这里row的类型是int*,而我们不能遍历一个int*数据。
正确的做法是:
int ia[3][4] = {0};
for(auto & row:ia){
for(auto col:row){
...
}
}
注意区别就在于,多了一个"&"!!当我们这样做后,编译器就不会把array转换成pointer,因此,row也是一个array,其格式是int[4],所以可以再次遍历。
总结:当我们在range for中使用multidimensional array时,除了最里面一个for,其他所有的for都应该是reference!
Pointer和Multidimensional Arrays
除了用range for遍历multidimensional array,我们也可以用pointer来遍历,在C++ 11中,有以下两种较为简洁的遍历方法。
int ia[3][4] = { 0 };
for (auto p = ia; p < ia+3; p++){
for (auto q = *p; q < *p + 4; q++){
cout << *q << endl;
}
}
int ia[3][4] = { 0 };
for (auto p =begin(ia); p != end(ia); p++){
for (auto q = begin(*p); q != end(*p); q++){
cout << *q << endl;
}
}
如果利用type alias,我们也可以完成上述的类似功能。
using int_array = int[4];
typedef int int_array[4];//这两个是等价的
for(int_array *p = ia;p!=ia+3;++p){
for(int *q = *p;q!=*p+4;++q)
cout<<*q<<endl;
}