理解向量中的 .begin 和 .end

Understanding .begin and .end in vectors

我正在从 this post 学习向量,它们从迭代器开始。他们定义 .begin 和 .end 如下:

begin() – Returns an iterator pointing to the first element in the vector

end() – Returns an iterator pointing to the theoretical element that follows the last element in the vector

然后他们给出了下面的代码片段,我添加了第三个for循环来表达我的问题。

#include<iostream>
#include<vector>

int main() {
    std::vector <int> g1; //creating a vector
    for (int i = 1; i <= 3; i++){
        g1.push_back(i);
    }
    std::cout << "Output of beginning and end values: ";
    for (auto i = g1.begin(); i != g1.end(); i++) {
        std::cout << *i << " "; 
    }
    std::cout << "\nOutput of beginning and end addresses: ";
    for (auto i = g1.begin(); i != g1.end(); i++) {
        std::cout << &i << " ";
    }
     //"Output of beginning and end values: 1 2 3"
     //"Output of beginning and end addresses: 0105FB0C 0105FB0C 0105FB0C"
    return 0;
}

我的困惑是 i 的地址保持不变,但 i 的值已更改。 i* 不意味着 i 只是取消引用吗?因此,如果地址未更改,则必须更改 i 的值,以便它能够具有不同的值。我想我可能将迭代器与指针混淆了。我知道 auto 基本上是类型推断,仅此而已。

所以我的问题是,如果向量中每个元素的地址都相同,i 的值会如何变化?

&i是局部变量i的地址。这不会改变。 *i 取消对迭代器的引用,return 是向量该元素的值。 &*i 将 return 指向向量中元素的指针。

所以你循环应该使用

std::cout << &*i << " ";

查看地址变化。

I think I may be confusing iterators with pointers

嗯,指针是迭代器,所以这是可以理解的。但并非所有的迭代器都是指针。也就是说,非指针也可以是迭代器。

I know that auto is basically type inference but that's about it.

在这种情况下,类型被推断为 std::vector<int>::iterator 因为这是 std::vector<int>::begin returns.

的类型

So my question is, how does the value of i change, if it's address is the same for every element in the vector?

i 的值被循环中的 i++ 改变。存储对象的地址在对象的整个生命周期中永远不会改变。不管该对象的类型是指针、其他迭代器还是根本不是迭代器。

为了更清楚地考虑类似的代码,但使用数组代替向量。

#include <iostream>
#include <iterator>

int main() 
{
    int a[] = { 1, 2, 3 };

    for ( auto p = std::begin( a ); p != std::end( a ); p++ )
    {
        std::cout << "The address of p is " << &p
                  << ", its value is " << p
                  << ", and the pointed value is " << *p
                  << '\n';
    }

    return 0;
}

程序输出可能看起来像

The address of p is 0x7ffcaf6a6830, its value is 0x7ffcaf6a683c, and the pointed value is 1
The address of p is 0x7ffcaf6a6830, its value is 0x7ffcaf6a6840, and the pointed value is 2
The address of p is 0x7ffcaf6a6830, its value is 0x7ffcaf6a6844, and the pointed value is 3

这部分输出的字符串

The address of p is 0x7ffcaf6a6830

没有被更改,因为它是局部变量(指针)p 本身的地址。

这部分字符串

its value is 0x7ffcaf6a683c

正在更改,因为在循环中指针的值已更改

for ( auto p = std::begin( a ); p != std::end( a ); p++ )
                                                        ^^^^

在每次迭代中,指针指向数组的下一个元素。

这部分字符串

and the pointed value is 1

也正在更改,因为由于取消引用指针而输出了指向的值。

同样的事情也发生在向量的迭代器上。