对于C++ Random Access Iterator(向量迭代器),迭代器之间的差异是如何计算的?
For C++ Random Access Iterator (vector iterator), how is the difference between iterators calculated?
我有以下代码来随机化随机访问迭代器中的元素 (vector<int>::iterator
) -
#include <vector>
#include <list>
#include <iterator>
#include <algorithm>
#include <stdlib.h>
#include <iostream>
using namespace std;
template<class RandomAccesIterator>
void randomize(RandomAccesIterator iterBegin, RandomAccesIterator iterEnd)
{
while (iterBegin != iterEnd)
{
int rand1 = rand();
auto iterdiff = iterEnd - iterBegin;
auto secondarg = iterBegin + rand1 % (iterdiff);
iter_swap(iterBegin, secondarg);
++iterBegin;
}
}
下面是 main() 函数:
int main()
{
//container used as to apply algorithm to.
list<int> List = {34,77,16,2,35,76,18,2,56};
//randomize example.
cout << "calling randomize on sorted vector: " << endl;
List.sort();
vector<int> temp(List.begin(), List.end());
cout << "before randomize: " << endl;
for (vector<int>::iterator it = temp.begin(); it != temp.end(); it++)
{
cout << *it << " ";
}
cout << endl;
randomize(temp.begin(),temp.end());
cout << "after randomize: " << endl;
for (vector<int>::iterator it = temp.begin(); it != temp.end(); it++)
{
cout << *it << " ";
}
cout << endl<<endl;
return 0;
}
randomize模板函数中,迭代器的差值(iterEnd - iterBegin)是怎么计算的?
我立即尝试了一些东西 window,看起来 iterEnd - iterBegin 是这样计算的(向量中有 9 个元素,下面的计算给出了 9 个)。我尝试了 vector<int>
中不同数量的元素,每次的答案都是正确的。计算是我们第一次在while循环中遇到iterEnd - iterBegin(即vector中的9个元素):
立即window-
1.
iterEnd
{-33686019}
[ptr]: 0x0080f9dc {-33686019}
[Raw View]: {...}
2.
iterBegin
{2}
[ptr]: 0x0080f9b8 {2}
[Raw View]: {...}
3.
0x0080f9dc-0x0080f9b8 //iterEnd - iterBegin gives 36.
36
4.
36/4 //Dividing 36 by 4, since an integer is 4 bytes (we are iterating over a vector of integers).
9
我也在 vector<int>
中尝试了 8 个元素,同样类型的计算在上面的步骤 4 中得到了 8 个元素。
我有几个问题:
- 我为获取向量中的元素数量而执行的步骤是否正确(上述步骤 1 至 4)?
- 在上面的第 4 步中,我将十进制的 36 除以 4 个字节。这如何给我正确的结果?如果我将 36 个字节除以 4 个字节,那么这将是有意义的,然后将得到 9 个元素。为什么将 十进制 36 除以 4 个字节给出正确答案?
请参阅:我正在使用以下编译器:Microsoft Visual Studio Enterprise 2019(版本 16.2.1)。操作系统平台是 64 位、基于 x64 的处理器。我正在构建 Debug x86 环境。 Windows 版本是 Windows 10 Pro
您的步骤是正确的,但这只是因为:
int
在你的系统 上正好是 4 个字节长
std::vector<int>::iterator
恰好在 您的系统 上简单地包装了一个原始指针 (int*
)
您可以使用 sizeof(int)
在 编译代码的任何系统 上评估正确的字节数,而不是对值 4 进行硬编码。
std::size_t numElements = (0x0080f9dc - 0x0080f9b8) / sizeof(int); // Better
关于你的第二个问题,你计算的36
不是无单位小数。原始指针的原始整数值(记住:std::vector<int>::iterator
简单地包装了一个 int*
所以它具有相同的大小)使用字节作为它们的隐式单位,所以你 是 实际上在您的步骤中逐字节划分。
最后,我建议避免使用这种指针算法(rationale). The standard already provides a function to calculate exactly this, std::distance
,它将在所有标准迭代器和您编译代码的任何系统上正常工作。
std::size_t numElements = std::distance(iterBegin, iterEnd); // Best
我有以下代码来随机化随机访问迭代器中的元素 (vector<int>::iterator
) -
#include <vector>
#include <list>
#include <iterator>
#include <algorithm>
#include <stdlib.h>
#include <iostream>
using namespace std;
template<class RandomAccesIterator>
void randomize(RandomAccesIterator iterBegin, RandomAccesIterator iterEnd)
{
while (iterBegin != iterEnd)
{
int rand1 = rand();
auto iterdiff = iterEnd - iterBegin;
auto secondarg = iterBegin + rand1 % (iterdiff);
iter_swap(iterBegin, secondarg);
++iterBegin;
}
}
下面是 main() 函数:
int main()
{
//container used as to apply algorithm to.
list<int> List = {34,77,16,2,35,76,18,2,56};
//randomize example.
cout << "calling randomize on sorted vector: " << endl;
List.sort();
vector<int> temp(List.begin(), List.end());
cout << "before randomize: " << endl;
for (vector<int>::iterator it = temp.begin(); it != temp.end(); it++)
{
cout << *it << " ";
}
cout << endl;
randomize(temp.begin(),temp.end());
cout << "after randomize: " << endl;
for (vector<int>::iterator it = temp.begin(); it != temp.end(); it++)
{
cout << *it << " ";
}
cout << endl<<endl;
return 0;
}
randomize模板函数中,迭代器的差值(iterEnd - iterBegin)是怎么计算的?
我立即尝试了一些东西 window,看起来 iterEnd - iterBegin 是这样计算的(向量中有 9 个元素,下面的计算给出了 9 个)。我尝试了 vector<int>
中不同数量的元素,每次的答案都是正确的。计算是我们第一次在while循环中遇到iterEnd - iterBegin(即vector中的9个元素):
立即window-
1.
iterEnd
{-33686019}
[ptr]: 0x0080f9dc {-33686019}
[Raw View]: {...}
2.
iterBegin
{2}
[ptr]: 0x0080f9b8 {2}
[Raw View]: {...}
3.
0x0080f9dc-0x0080f9b8 //iterEnd - iterBegin gives 36.
36
4.
36/4 //Dividing 36 by 4, since an integer is 4 bytes (we are iterating over a vector of integers).
9
我也在 vector<int>
中尝试了 8 个元素,同样类型的计算在上面的步骤 4 中得到了 8 个元素。
我有几个问题:
- 我为获取向量中的元素数量而执行的步骤是否正确(上述步骤 1 至 4)?
- 在上面的第 4 步中,我将十进制的 36 除以 4 个字节。这如何给我正确的结果?如果我将 36 个字节除以 4 个字节,那么这将是有意义的,然后将得到 9 个元素。为什么将 十进制 36 除以 4 个字节给出正确答案?
请参阅:我正在使用以下编译器:Microsoft Visual Studio Enterprise 2019(版本 16.2.1)。操作系统平台是 64 位、基于 x64 的处理器。我正在构建 Debug x86 环境。 Windows 版本是 Windows 10 Pro
您的步骤是正确的,但这只是因为:
int
在你的系统 上正好是 4 个字节长
std::vector<int>::iterator
恰好在 您的系统 上简单地包装了一个原始指针 (
int*
)
您可以使用 sizeof(int)
在 编译代码的任何系统 上评估正确的字节数,而不是对值 4 进行硬编码。
std::size_t numElements = (0x0080f9dc - 0x0080f9b8) / sizeof(int); // Better
关于你的第二个问题,你计算的36
不是无单位小数。原始指针的原始整数值(记住:std::vector<int>::iterator
简单地包装了一个 int*
所以它具有相同的大小)使用字节作为它们的隐式单位,所以你 是 实际上在您的步骤中逐字节划分。
最后,我建议避免使用这种指针算法(rationale). The standard already provides a function to calculate exactly this, std::distance
,它将在所有标准迭代器和您编译代码的任何系统上正常工作。
std::size_t numElements = std::distance(iterBegin, iterEnd); // Best