方式一:
#include <vector>
#include <iostream> int main() { // 初始化一个2x3的二维向量(矩阵) std::vector<std::vector<float>> matrix = { {1.0, 2.0, 3.0}, // 第一行 {4.0, 5.0, 6.0} // 第二行 }; // 遍历并打印矩阵 for (const auto& row : matrix) { for (auto value : row) { std::cout << value << " "; } std::cout << std::endl; } return 0;
}
在C++中,当你使用范围基于的for循环(for (element : range)
)时,你实际上是在遍历一个给定的范围(range
),并且每次迭代都会从该范围中提取出一个元素(element
)供循环体使用。在这个特定的例子中,row
并不是每行的“地址”,而是对当前正在遍历的行的引用(由于你在外层循环中使用了 const auto& row
)。但是,这里的重点是 row
代表了二维向量 matrix
中的一行,即一个 std::vector<float>
类型的对象。
当你写 for (float value : row)
时,你实际上是在告诉编译器:“对于 row
中的每一个元素(即 row
这个 std::vector<float>
中的每一个 float
值),都将其赋值给 value
,并执行循环体。” 这里的关键是理解 row
是一个可以迭代的容器(在这个例子中是 std::vector<float>
),而范围基于的for循环能够自动处理这种容器的迭代。
编译器会处理迭代器的细节,但对于你来说,你只需要知道你可以像这样遍历 row
中的每个元素即可。具体来说,编译器会生成一个迭代器(在这个情况下是 std::vector<float>::iterator
或 std::vector<float>::const_iterator
,取决于 row
是否被声明为 const
),并使用它来遍历 row
中的所有元素。但是,这些细节对于编写代码的你来说是隐藏的。
因此,即使 row
是对二维向量中一行的引用,你仍然可以直接使用范围基于的for循环来遍历这一行的所有元素,而无需关心迭代器的具体实现。这是C++标准库提供的一种非常便捷和直观的遍历容器元素的方式。
方式二 :
#include <vector>
#include <iostream> int main() { // 初始化一个2x3的二维向量(矩阵) std::vector<std::vector<float>> matrix = { {1.0, 2.0, 3.0}, // 第一行 {4.0, 5.0, 6.0} // 第二行 }; // 获取行数(外层向量的元素个数) int rows = matrix.size(); // 遍历行 for (int i = 0; i < rows; ++i) { // 获取当前行的元素个数(内层向量的元素个数) int cols = matrix[i].size(); // 遍历列 for (int j = 0; j < cols; ++j) { // 打印当前元素 std::cout << matrix[i][j] << " "; } // 打印完一行后换行 std::cout << std::endl; } return 0;
}