方式一:
#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;
}