In the previous article C++ iterator (and reverse iterator)
, we saw the basic usage of iterators.
Now let's look at a strange phenomenon
Unexpected subtraction operation
What does the unsigned number 0 minus 1 become? ? It is known that size_t is generally of unsigned long long type.
#include <iostream>
using namespace std;
int main(void)
{
size_t i = 0;
--i;
cout << i << endl;
return 0;
}
The above program output:
Why 18446744073709551615? This number is actually 2^64-1.
Binary is: 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
That is, the complement of -1. Computer numerical types are represented by two's complement codes .
According to the definition of "Computer Composition Principles" Tang Shuofei 2nd Edition 6.1.2 Unsigned Numbers 6.1.3 Signed Numbers' Complement Code. We can know that the complement of -1 is a binary number with 64 bits all being 1.
In computers, subtraction is calculated using the complement of addition. The result of 0-1 is [0] complement + [-1] complement = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 + 11111111 1111 1111 11111111 11111111 11111111 11111111 11111111 11111111 = 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
size_t type cannot be iterated in reverse order
Consider the following program, what is the output?
#include <iostream>
#include <vector>
using namespace std;
void test_reverse_iterate_by_index(void)
{
cout << "reverses iterate vector by index:";
vector<int> arr{123};
for (size_t i = arr.size()-1; i >= 0 ; --i)
{
cout << arr[i] << " ";
}
arr.rbegin();
cout << endl;
}
int main(void)
{
test_reverse_iterate_by_index();
return 0;
}
Actually the program will crash
Why is this happening?
As mentioned before, unsigned numbers have no negative numbers and all binary bits represent positive integers.
When i subtracts 1 from 0, through the previous analysis, we can know the result of 0-1: 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 As an unsigned number, when compared with 0, it is obviously greater than 0.
This causes the program to access arr[11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111], which is obviously out of bounds.
That is, the program pops up Assert failed: out of range.
Reverse iterator reverse_iterator
Therefore, when we need to traverse the container in reverse order, the standard library provides a reverse iterator that allows us to iterate the container conveniently and safely:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> a{ 0,1,2,3,4,5,6,7,8,9 };
//rbegin() 获取逆序迭代器的第一个迭代器;
//rend() 获得逆序迭代器的最后一个迭代器的下一个位置(哨兵)
for (auto itr = a.rbegin(); itr != a.rend(); ++itr)
{
cout << *itr << " ";
}
return 0;
}
Program output:
Reverse iterator reference: