C++新特性03_迭代器iterator及类型推导auto(迭代器:用于容器中数据遍历;动态数组(vector)和链表(list)遍历;堆上下限标志位;类型推导auto:编译时自动推导数据类型)

本文介绍了C++中的迭代器和类型推导关键字auto的使用。迭代器是用于遍历容器中数据的标准库工具,无论容器是数组、动态数组如vector,还是链表如list。文章详细展示了不同数据结构的遍历方式,强调了迭代器在统一访问数据结构中的作用。同时,文章探讨了类型推导auto如何简化代码,让编译器自动推导变量类型,提高开发效率。最后,文章展示了C++11以后更简洁的遍历语法,并给出了相关学习资源链接。

1.迭代器:用于容器中数据的遍历操作

数据结构:描述数据之间的关系及操作。数据结构通常由代码实现,也就是下面提到的动态数组等。
stl中存在一些常见的已经封装好(开箱即食)数据结构相关的模板类,例如vector(动态数组)list(链表), stack(栈)queue(队列)map(hash表/红黑树,C++中map的内部是用红黑树实现,但外在表现形式是hash表)等容器。这些类通常都有一些最基本的操作,例如:增加,删除,修改,遍历等等。

C++为了方便统一,采用了设计模式中的迭代器模式,也就是统一的提供了一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。我们一般对这些数据结构的遍历都可以无脑使用迭代器,而不关心内部存储的差异。

1.1 普通数组与动态数组定义及遍历方式

1.1.1 数组:普通的数组, 一旦申请,不能再扩增

定义及遍历方式:

int ary[5] = { 1, 2, 3, 4, 5 };
int* pAry = new int[5];//使用new创建pAry int数组指针
//遍历方式
	for (int i = 0; i < sizeof(ary); i++){
	    std::cout << ary[i] << std::endl;
	}

1.1.2 动态数组:vector,不用指定其大小,会根据数组当前的使用情况进行动态的扩容

定义及遍历方式:
普通访问方法:需要知道数据结构,数据是按照一定的顺序排布,但是其他数据结构可能不是,就无法使用
迭代器的方式:C++为了方便统一,采用了设计模式中的迭代器模式,也就是统一的提供了一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。就是一种套路

//容器(数据的封装)---动态数组 不用指定其大小,会根据数组当前的使用情况进行动态的扩容
	//模板类型
	std::vector<int> v;

	//插入数据
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);

//普通访问方法,需要知道数据结构,数据是按照一定的顺序排布
//但是其他数据类型可能不是
	for (int i = 0; i < v.size(); i++){
	    std::cout << v[i] << std::endl;
	}

//使用迭代器的方式遍历数组
	std::vector<int>::iterator it; //迭代器,模板类中的内部类
	for (it = v.begin(); it != v.end(); it++) {
		std::cout << *it << std::endl; //用*it来访问模板类的具体的值
	}

vector中数据保存在堆上,以fd fd fd fd 作为上下限的标志位
在这里插入图片描述

1.2 链表的遍历方式

迭代器看着是比较复杂,但是需要用统一的眼光去看待问题,不仅是动态数组,链表等其他数据结构也是可以用迭代器来进行遍历。

//统一的遍历方式 链表
	std::list<std::string> l;
	l.push_back("hello1");
	l.push_back("hello2");
	l.push_back("hello3");

	for (std::list<std::string>::iterator it2 = l.begin(); it2 != l.end(); it2++) {
	    std::cout << (*it2).c_str() << std::endl; //* it 来访问模板类的具体的值
	}

迭代器中关于类型的书写是不是感觉特别麻烦呢?碰到这种一下就懵逼了!
在这里插入图片描述

2.类型推导auto:编译器在编译时自动推导出数据类型

在传统 C 和 C++中,参数的类型都必须明确定义,这其实对我们快速进行编码没有任何帮助,尤其是当我们面对一大堆复杂的模板类型时,必须明确的指出变量的类型才能进行后续的编码,这不仅拖慢我们的开发效率,也让代码变得又臭又长。

C++ 11 引入了 autodecltype 这两个关键字实现了类型推导,让编译器来操心变量的类型。这使得 C++ 也具有了和其他现代编程语言一样,某种意义上提供了无需操心变量类型的使用习惯。

auto 在很早以前就已经进入了 C++,但是他始终作为一个存储类型的指示符存在,与 register 并存。在传统 C++ 中,如果一个变量没有声明为 register 变量,将自动被视为一个 auto 变量。而随着 register 被弃用,对 auto 的语义变更也就非常自然了。

替代前面提到的数据类型手写的形式,编译器在编译时自动推导出数据类型

	//auto 类型推导关键字
	for (auto it2 = l.begin(); it2 != l.end(); it2++) {
	    std::cout << (*it2).c_str() << std::endl; //* it 来访问模板类的具体的值
	}

一些其他的常见用法:

auto i = 5;             // i 被推导为 int
auto arr = new auto(10) // arr 被推导为 int *

注意auto 不能用于函数传参,因此下面的做法是无法通过编译的(考虑重载的问题,我们应该使用模板):

int add(auto x, auto y);

此外,auto 还不能用于推导数组类型:

#include <iostream>

int main() {
 auto i = 5;

 int arr[10] = {0};
 auto auto_arr = arr;
 auto auto_arr2[10] = arr;

 return 0;
}

3.编译器进化后遍历的写法

C++模仿javascrip等脚本,对遍历这种功能进行封装,采用以下这种形式进行遍历。

	for(std::string str : l){
	    std::cout << str.c_str() << std::endl;
	}

4.再进化,类型推导的写法

	for (auto str : l) {
		std::cout << str.c_str() << std::endl;
	}

5.学习视频地址:迭代器及类型推导auto
6.学习笔记:迭代器及类型推导auto笔记

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十月旧城

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值