关于迭代器遍历及auto关键词

在使用vector容器或者字符串时,很经常会用到一些遍历操作,除了使用下标遍历之外,使用迭代器遍历也是超级方便,但是迭代器也有有一些小坑,一不注意就会编译出错,所以特意总结一下。

迭代器

在这里插入图片描述
迭代器很很多接口,不过最重要要搞清楚迭代器指向的位置!!
str.begin();指向字符串的第一个字符的位置
str.end();指向字符串的最后一个字符的后一个位置;
str.rbegin();指向字符串的最后一个字符的位置;
str.rend();指向第一个字符串的前一个位置;

举个例子:
在这里插入图片描述

使用迭代器遍历

迭代器的使用方式和指针类似
设计规范:
1.begin迭代器:指向第一个元素的位置;
2.end迭代器:指向最后一个元素的末尾;
3.访问数据:通过解引用完成:*,->
4.迭代器移动:++移动到下一个元素的位置,移动到上一个元素的位置;
5.位置的判断:支持!=,==
有些容器具有反向迭代器
6.rbegin迭代器:指向最后一个元素的位置;
7.rend迭代器:指向第一个元素的前一个位置

依然举个例子:

// iterator begin(); const_iterator begin() const;
// iterator end(); const_iterator end() const;

void stringTraverse() {
	string str1 = "12345";
	string::iterator it = str1.begin();
	while(it != str1.end()){
		cout << *it << " ";
		// 可以 *it = 'a';
		++it;
	}
	cout<<endl;
}

这里可能有同学会有疑问,为什么循环的终止条件是iter!=str.end(),但是还能便利字符串里的最后一个字符呢?往前翻一翻,答案一目了然,因为end()指向的最后一个字符串的后一个位置

还有心细的同学发现,第一张图片中除了有刚刚介绍的四个接口以外,还有4个接口:cbegin,cend,crbegin,crend;有什么区别呢?其实很简单 这些接口的返回类型都是constiterator,也就是只读,不能修改对应的值。
再举个例子:

// iterator begin(); const_iterator begin() const;
// const_iterator cbegin() const

void stringTraverse() {
	string str1 = "12345";
	string::iterator it = str1.begin();
	while(it != str1.end()){
		cout << *it << " ";
		// 可以 *it = 'a';
		++it;
	}
}

void stringTraverse() {
	const string str3 = "12345";
	string::const_iterator it3 = str3.cbegin();
	while (it3 != str3.cend()) {
		// 不可以 *i = 'a';
		cout << *it3 << "";
		++it3;
	}
	cout << end1;
}

使用auto遍历

auto是一个C/C++语言存储类型,仅在语句块内部使用,初始化可为任何表达式,其特点是当执行流程进入该语句块的时候初始化可为任何表达式。简单说就是 auto关键字可以自动给变量一个相应的数据类型,在遍历的时候就特别方便,比如:

void stringTraverse() {
	string str1 = "12345";
	for(auto iter = str.begin(); iter != str.end(); iter++) {
        cout << *iter; //迭代器访问
    }
    cout<<endl;
}

甚至可以更简单:

void stringTraverse() {
	string str1 = "12345";
	for(auto iter : str1) {
        cout << *iter; //迭代器访问
    }
    cout<<endl;
}

关于auto的一些碎碎念

规则1:声明为auto(不是auto&)的变量,忽视掉初始化表达式的顶层const。即对有const的普通类型(int
、double等)忽视const,对常量指针(顶层const)变为普通指针,对指向常量(底层const)的常量指针(顶层cosnt)变为指向常量的指针(底层const)。
规则2:声明为auto&的变量,保持初始化表达式的顶层const或volatile 属性。
规则3:若希望auto推导的是顶层const,加上const,即const auto。
个人认为,上述的推导规则,不太容易理解,本人也不太理解,可以参照参考博客中的例子进行理解,对于初学者理解auto来说,主要知道auto用来代替冗长复杂或未知的变量声明即可。

关于string和vector的碎碎念

这里也给大家拓展一下字符串和数组有什么差别,

字符串是若干字符组成的有限序列,也可以理解为是一个字符数组,但是很多语言对字符串做了特殊的规定,接下来我来说一说C/C++中的字符串。

在C语言中,把一个字符串存入一个数组时,也把结束符 '\0’存入数组,并以此作为该字符串是否结束的标志。

例如这段代码:

char a[5] = "asd";
for (int i = 0; a[i] != '\0'; i++) {
}

在C++中,提供一个string类,string类会提供 size接口,可以用来判断string类字符串是否结束,就不用’\0’来判断是否结束。

例如这段代码:

string a = "asd";
for (int i = 0; i < a.size(); i++) {
}

那么vector< char > 和 string 又有什么区别呢?

其实在基本操作上没有区别,但是 string提供更多的字符串处理的相关接口,例如string 重载了+,而vector却没有。

所以想处理字符串,我们还是会定义一个string类型。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值