数组(或其他数据结构)的遍历是编程中一项常见的任务。到目前为止,我们已经介绍过多种遍历方法:使用循环和索引(for-loops 和 while loops),使用指针和指针运算,使用基于范围的for循环:
#include <array>#include <cstddef>#include <iostream>int main(){ // In C++17, the type of variable data is deduced to std::array<int, 7> // If you get an error compiling this example, see the warning below std::array data{ 0, 1, 2, 3, 4, 5, 6 }; std::size_t length{ std::size(data) }; // while-loop with explicit index std::size_t index{ 0 }; while (index < length) { std::cout << data[index] << ' '; ++index; } std::cout << '\n'; // for-loop with explicit index for (index = 0; index < length; ++index) { std::cout << data[index] << ' '; } std::cout << '\n'; // for-loop with pointer (Note: ptr can't be const, because we increment it) for (auto ptr{ &data[0] }; ptr != (&data[0] + length); ++ptr) { std::cout << *ptr << ' '; } std::cout << '\n'; // ranged-based for loop for (int i : data) { std::cout << i << ' '; } std::cout << '\n'; return 0;}
#include <array>#include <iostream>int main(){ std::array data{ 0, 1, 2, 3, 4, 5, 6 }; auto begin{ &data[0] }; // note that this points to one spot beyond the last element auto end{ begin + std::size(data) }; // for-loop with pointer for (auto ptr{ begin }; ptr != end; ++ptr) // ++ to move to next element { std::cout << *ptr << ' '; // Indirection to get value of current element } std::cout << '\n'; return 0;}
#include <array>#include <iostream>#include <iterator> // For std::begin and std::endint main(){ std::array array{ 1, 2, 3 }; // Use std::begin and std::end to get the begin and end points. auto begin{ std::begin(array) }; auto end{ std::end(array) }; for (auto p{ begin }; p != end; ++p) // ++ to move to next element { std::cout << *p << ' '; // Indirection to get value of current element } std::cout << '\n'; return 0;}
#include <array>#include <iostream>int main(){ std::array array{ 1, 2, 3 }; // This does exactly the same as the loop we used before. for (int i : array) { std::cout << i << ' '; } std::cout << '\n'; return 0;}
实际上,基于范围的for循环会在背地里调用被遍历类型的 begin() 和 end() 。std::array 是具有 begin 和 end 成员函数的,所以它可以被用于基于范围的循环。C语言风格的固定数组,也可以通过 std::begin 和 std::end 来获取起止点,所以它也可以被用于基于范围的for循环。动态数组就不好使了,因为std::end 函数对它无效(类型信息不包含数组长度)。
Much like pointers and references, iterators can be left “dangling” if the elements being iterated over change address or are destroyed. When this happens, we say the iterator has been invalidated. Accessing an invalidated iterator produces undefined behavior.