本书的第三章几乎就是在讲明白迭代器,数组下标和指针之间的关系。
1,首先迭代器的运算类似于指针运算,迭代器类似于指针,但是迭代器并不使用取地址符,而是通过其类中的begin()函数和end()函数来取到第一个元素的位置和最后一个元素的下一个位置。其解引用的方式和指针一样就是加个*。迭代器支持的运算指针也全都支持,也因此迭代器几乎可以看作指针的一个父类
2,数组下标其实就是数组中首个元素的位置加上下标值后的位置所对应的一个指针(这样也能解释为什么java中数组的元素可通过形参改变了。)
比如下面这个
p // 如果p是一个数组的话那么p这个名字指的就是p数组首元素的指针
p[2] // 等价于*(p + 2),即首元素之后的第二个位置的指针所对应的元素
基于这样的理解,当p指的不在是首个元素时,我们甚至可以看到这样的写法
int *m = &p[2];
int k = m[-2];//等价于int k = p[0];
只要在数组已有的内存空间里面,下标是负数也是可以的
3,c++似乎并不把string类看成一个字符数组(c++字符串中的字符可通过下标索引,不用使用java中的charAt方法),比如说
如果看成是数组的话,很显然
string s1 = "hello";
string s2 = "world";
string s = s1 + " " + s2;
这段代码是不能运行的,因为两个指针是不能相加的。可事实上这串代码可运行并不会报错,也证明了c++尽管仍旧支持c风格的字符串,但又不只是这样。
4,数组与迭代器的区别在于数组并不是一个类,因此它的begin和end用法,只能这样用
int *beg = std::begin(ia);
int *last = std::end(ia);
5,java中我们一般通过length方法取到数组长度,然后实现多维数组的遍历,而在c++中我们可以这样写
for(auto i = begin(ia); i != end(ia); i++){
for(auto j = begin(*i); j != end(*i); j++){ // ia是一个二维数组
}}
(我非常喜欢c++中的写法,似乎能让我更加理解语言在做些什么)
6, 数组不能进行拷贝 没有m = n这种写法。java中这种写法其实应该看成
auto *m = n;
即通过m你会改变n数组内部的值。
7,string字符串默认会在最后加个空白字符。
8, vector容器的元素似乎也可以直接通过下标获得