c++ - 对于C++随机访问迭代器( vector 迭代器),迭代器之间的差异是如何计算的?

标签 c++ iterator random-access

我有以下代码来随机化随机访问迭代器中的元素 ( 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)?

我在立即窗口中尝试了一些操作,看起来 iterEnd - iterBegin 的计算方式如下( vector 中有 9 个元素,下面的计算给出 9)。我尝试了 vector<int> 中的各种数量的元素,而且每次的答案都是正确的。这是我们第一次在 while 循环中遇到 iterEnd - iterBegin 的计算(即 vector 中的 9 个元素):

在立即窗口中 -

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. 我为获取 vector 中的元素数量而执行的步骤是否正确(上述步骤 1 到 4)?
  2. 在上面的步骤 4 中,我将 36(十进制)除以 4 个字节。这如何给我正确的结果?如果我将 36 字节除以 4 字节,那么就会得到 9 个元素。为什么十进制 36 除以 4 个字节会得到正确的答案?

请参阅:我正在使用以下编译器:Microsoft Visual Studio Enterprise 2019(版本 16.2.1)。操作系统平台是64位、基于x64的处理器。我正在调试 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 )。标准已经提供了一个函数来精确计算这个, std::distance ,并且它将在所有标准迭代器以及您编译代码的任何系统上正常工作。

std::size_t numElements = std::distance(iterBegin, iterEnd);  // Best

关于c++ - 对于C++随机访问迭代器( vector 迭代器),迭代器之间的差异是如何计算的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59607594/

相关文章:

标准模板库 : <error-type>*? 的 C++ IntelliSense 错误

java - 另一种使用 RandomAccessFile 编写学生而不使用静态数组的方法

c++ - 所有 end() 迭代器都等同于集合类型吗?

c++ - 如何以编程方式查找为 Linux 中的特定网络设备配置的 IP 地址/网络掩码/网关?

c++ - Doxygen 重复带有默认参数的 C++ 函数

c++ - 当多次链接 DLL 时,导出的全局变量会发生什么情况?

python - 如何在 Python 中查找空列表的所有索引

android - 我如何读取连接到 Android 设备的 USB 闪存的第一个扇区?

c - 在 C 中编辑/修改和删除随机访问文件中的记录

c++ - QThread 中的堆栈大小