原创
【博客大赛】《C++ Primer》学习笔记(十)Arrays
Array是容器的一种。
和Vector类似,Array提供了相同数据类型的对象集合;不同于Vector,Array有固定的长度。
因此,Array提高了运行效率,降低了灵活性。
Array的长度必须在编译时指定,因此它的长度必须是一个常量表达式。
Array必须指定类型,不能使用auto去初始化它的类型。
Array的类型不能是引用。
const unsigned sz = 3;
int ia1[sz] = {0, 1, 2};
int a2[] = {0, 1, 2};
int a3[5] = {0, 1, 2};
string a4[3] = {"hi", "bye"};
字符型的array有一种特殊的初始化方式:
char a5[] = "C++";
这里要注意的是,字符串末尾的'\0'也会被拷贝进来,因此a5的长度是4。
Array不可被另一个Array复制,也不可被另一个Array赋值。
a6 = a5,这个表达式是非法的。
----------------
Array的指针和引用:
int *ptrs[10]; //ptrs是包含10个整型指针的矩阵
int &refs[10] = /* ? */; //错误的表达,没有包含引用的矩阵
int (*Parray)[10] = &arr; //Parray是一个指针,指向10个整型元素的矩阵地址
int (&arrRef)[10] = arr; //arrRef是一个引用,等于10个整型元素的矩阵名
int *(&array)[10] = ptrs; //array是一个引用,等于包含10个整型指针的ptrs
怎么理解Array的xxx指针和xxx引用的复杂结合呢?
从变量名字开始,从里往外理解。
----------------
Array的访问:
可以使用range for,也可以使用subscript。
如果使用subscript,下标值的数据类型是(无符号的架构相关的)size_t。
Array不会检查是否越界,这得由程序员来保证。
Array和指针的关系紧密,实际上,当我们使用array时,就在使用指向array[0]的指针。
如果使用auto,则返回指针:
int ia[] = {0, 1, 2};
auto ia2(ia); //ia2是指针,相当于ia2(&ia[0])
如果使用decltype,则返回array:
int ia[] = {0, 1, 2};
decltype(ia) ia3 = {4, 5, 6};
这也说明了auto和decltype的区别,以及它们适用的不同场景。
指针是作用于矩阵的迭代器。
我们可以使用指针指向第一个元素:
int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *p = arr;
int *p1 = &arr[0];
我们可以使用指针指向最后一个元素之后的那个不存在的元素:
int *e = &arr[10];
----------------
Array的begin和end功能
和容器一样,Array也提供了begin和end功能,但它们是普通的函数,而不是成员函数:
int ia[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *beg = begin(ia);
int *last = end(ia);
指针可以进行算术运算:
int arr[5] = {0, 1, 2, 3, 4};
int *ip = arr;
int *ip2 = ip + 4;
注意指针的算术运算不能超过Array的范围,否则就直接越界了。
指针的算术运算,和迭代器类似。
指针之差的数据类型是prtdiff_t,类似size_t,它也是架构相关,定义在cstddef中。
prtdiff_t是有符号的,迭代器之差的数据类型difference_type类似。
指针在同一个Array中的比较才有意义。
没关系的两个指针的比较没有实际意义,即使能够得出它们的地址高低。
*(arr + 4)相当于arr[4]。
下标和指针的含义,对Array来说是一样的:
int *p = &ia[2];
int j = p[1];
int k = p[-2];
Library type的下标必须是无符号的数,而buildin type的下标则没有这个要求。
文章评论(0条评论)
登录后参与讨论