迭代器,数组和指针瞎扯扯
2015-08-15 14:06
429 查看
迭代器----不使用取地址符的“指针”
除了下标运算符之外的更规范的用来访问容器的机制就是迭代器,C++有很多容器,他们都支持迭代器,只有很少数支持下标运算符,string 并非是容器,但 string 也支持迭代器。虽然并没有明确说明迭代器就是指针,但是他俩真的是很像,迭代器也是对对象的间接访问,迭代器也有有效和无效之分,和指针的区别仅在于迭代器不使用取地址符,有迭代器的类型同时拥有返回迭代器的成员,如 begin 和 end 成员。end 返回的迭代器不指向某个元素,不能对其进行递增和解引用操作。
auto b = v.begin() , e = v.end(); //b表示v的第一个元素,e表示v的尾元素的下一个位置
迭代器的运算符(怎么看怎么像指针
) :
*iter //返回迭代器iter所指元素的引用 iter->men //解引用iter并获取该元素名为men的成员 ++iter //指向iter容器中的下一个元素 - - iter //指向iter容器中的上一个元素 //判断两迭代器是否指向同一个元素或同一容器的尾后迭代器 iter1==iter2 iter1 !=iter2
C++在for循环中习惯用 != 而非 <= 进行判断,原因是所有的标准库容器都定义了 != 和 == 而未定义 <= 。(大家都爱迭代器
)
迭代器的类型比较神秘,标准库使用 iterator 和 const_iterator 来表示迭代器的类型。const_iterator 就像指向常量的指针,只能读不能写。编译器默认是对象是常量就返回const_iterator ,不是常量就返回 iterator 。有时候这样的特性并不尽如人意,如果不希望修改对象的话,可以使用 cbegin 和 cend ,必然能得到
const_iterator。
但凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加或删除元素(并不完全正确),可能会发生时迭代器失效的情况。
数组---诸多限制的东东
同 vector 相同,只是大小固定,必须通过地址来访问其元素。灵活性不高,不允许拷贝数组,或者用数组为其他数组赋值。数组有很复杂的声明,理解数组的声明不能用从右到左的方法,而是使用从内到外的方法。
int *ptrs[10]; //ptr是含有10个整形指针的数组 int &refs[10] = /* ? */; //错误,不存在引用的数组(引用并非对象,数组是同一对象的集合) int *(&array)[10] = /* */ //array是数组的引用,该数组含有10个整形指针
上面第三例,由内到外,首先离括号内,array 是一个引用,看括号右边,发现 array 引用的对象是一个大小为 10 的数组,再往左看,数组的元素是整形指针,所以,综上 array 就是一个含有 10 个 int 型指针的数组的引用。
数组下标越界是很常见的问题,一定要小心防范。
在使用数组名字的地方,编译器会自动的将其转换为一个指向数组首元素的指针。
现代的C++程序应当尽量使用 vector (标准库容器) 和迭代器,而非内置数组和指针。应尽量使用 string ,避免使用C风格的基于数组的字符串。
在C++中明确来说并不存在多维数组,多维数组其实表示的是数组的数组。
使用范围for语句处理多维数组时,不管对数组元素有何操作,最外层的循环必须使用引用,否则会被编译器自动转换成指向该数组内首元素的指针,这样内存的循环就可能不合法。
int ia[3][4]; for(auto row : ia) //row的类型是int* for(auto col : row) //在int*中遍历,这显然是不对的
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- 设计模式之行为型模式 - 调用行为的传递问题
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- ruby 数组使用教程
- Ruby中的迭代器详解
- Ruby中Block和迭代器的使用讲解
- Ruby中的数组和散列表的使用详解
- C#实现AddRange为数组添加多个元素的方法
- C#动态调整数组大小的方法
- Lua中调用C++函数示例
- 详解Lua中的数组概念知识
- Lua中的迭代器浅析
- Lua中的迭代器和泛型for介绍
- Lua教程(一):在C++中嵌入Lua脚本
- Perl中的列表和数组学习笔记
- Lua教程(二):C++和Lua相互传递数据示例
- 探索PowerShell (八) 数组、哈希表(附:复制粘贴技巧)