《C++ Primer》读书笔记-第三章 05 数组

来源:互联网 发布:photoshop cs6 for mac 编辑:程序博客网 时间:2024/06/05 02:55
作者:马志峰
链接:https://zhuanlan.zhihu.com/p/23573899
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

声明:

  • 文中内容收集整理自《C++ Primer 中文版 (第5版)》,版权归原书所有。
  • 原书有更加详细、精彩的释义,请大家购买正版书籍进行学习。
  • 本文仅作学习交流使用,禁止任何形式的转载
  1. 定义和初始化
  2. 访问数组元素
  3. 指针和数组

数组与vector类似,也是存放类型相同的对象的容器

区别是,数组的大小确定不变,需要在定义时指定

定义和初始化

维度必须是常量

数组维度必须是一个常量表达式,保证在编译时维度是已知的

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()是constexpr时正确

列表初始化

使用列表初始化时,可以忽略维度,编译器会自动计算

int az[] = { 0, 1, 2 };

如果指明维度,需要保证列表中元素的个数小于维度

string a4[3] = { "hi", "bye" };

字符数组有一种额外的初始化形式,使用字符串初始化

char a2[] = "c++";  char a4[6] = "daniel";

此时要注意字符串末尾还有一个空字符,a2的维度是4,a4出错,因为没有位置存放空字符

复杂的声明

int *ptrs[10];  int (*Parray)[10] = &arr;  int (&arrRef)[10] = arr;  int *(&arry)[10] = ptrs;

理解的方法还是从右到左,有圆括号时,括号优先

对于ptrs,从右向左,首先知道它的维度是10,然后它的名字是ptrs,然后知道数组中存放的是int *,因此ptrs是含有10个整型指针的数组

对于Parray,括号优先,括号里面知道它是一个指针,然后从右向左,知道它指向一个维度为10的数组,再向左知道数组中元素是int类型,因此Parray是指向一个含有10个整数的数组

后面两个留给大家

数组元素的访问

  1. 范围for
  2. 下标
  3. 迭代器(指针)

1和2与前面的用法一样

数组下标通常定义成size_t类型,它是一种机器相关的无符号类型

指针也是迭代器

指向数组元素的指针比普通指针拥有更多的功能,string和vector的迭代器支持的自动,它全支持

数组有两个特性,也是和迭代器相关的

  1. 很多用到数组名的地方,都会自动地把数组名替换为一个指向数组首元素的指针,这个可以理解是为了方便得到起始位置
  2. 通常来说尝试获取一个不存在的对象的地址是非法的,但是允许获取数组尾后元素的地址

对于第1点

string nums[] = { "one", "two" };  string *p = &nums[10];

p是指向数组首元素的指针,但还有更简单的写法

string *p = nums;

对于第2点

下面是一个看上去非法的语法

int arr[] = { 0, 1, 2 };  int *p = &arr[3];

尽管3这个下标已经越界了,仍允许我们这么多,为的就是获得尾后指针

有了起始位置和结束位置,以及递增和解引用等操作,指向数组元素的指针也能行使和迭代器一样的职责了

当然,c++总是在进步的。c++11在iterator头文件中提供了两个函数begin和end,可以方便安全的获得数组首尾迭代器

int *beg = begin( arr );  itn *last = end( arr );

指向数组元素的指针与下标运算

int ia[] = { 0, 2, 4, 6, 8 };  int *p = &ia[2];  int j = p[1];  int k = p[-2];

p[1]等价于*(p+1)
p[-2]等价于*(p-2)

数组与vector

数组还可以用来初始化vector对象,只需要指明待拷贝区域的首尾元素地址就可以了

int arr[] = { 0, 1, 2, 3 };  vector<int> ivec( begin(arr), end(arr) );

建议:尽量使用vector和string,而非数组。数组和指针容易产生一些概念和理解上的错误

上面用数组来初始化vector的机制,有助于我们用vector来代替数组

那么,字符数组能否转换成string呢

允许使用以空字符结束的字符数组来初始化string对象或为string对象赋值

当然,如果需要也可以把string对象转换为指向字符的指针

const char *str = s.c_str();
0 0