迭代多维数组

时间:2015-10-23 19:04:13

标签: c++ arrays

假设我想为多维数组中的每个数字做一些事情。我发现你可以获得第一个数字的指针然后使用use pointer添加。例如,以下代码打印数字112

double a[2][3][2] = {{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}};
double *p = &a[0][0][0];
for (int i = 0; i < 12; i++)
    cout << *(p + i) << endl;

以这种方式将多维数组视为平坦是否是不同寻常的?如果是这样,这样做的首选方式是什么?另外,有没有更简单的方法来编写double *p = &a[0][0][0];来获取多维数组中第一个数字的指针(就像你只能为一维数组写double *p = a;一样) ?

3 个答案:

答案 0 :(得分:6)

是的,多维数组保证是平的。但是,最好是这种事情。如果你想在多维数组上进行平面迭代,我认为最好在其中引入一个范围视图:

template <typename T>
struct Flat {
    auto begin() { return first(arr); }
    auto end() {
        return begin() + sizeof(arr)/sizeof(*begin());
    }

    template <typename X> X* first(X& val) { return &val; }
    template <typename X, size_t N> auto first(X(&val)[N]) { return first(*val); }

    T& arr;
};

template <typename T>
Flat<T> flatten(T& arr) {
    return Flat<T>{arr};
}

只需使用那个:

for (double d : flatten(a)) {
    std::cout << d << std::endl;
}

否则,声明p的唯一其他方式就像double *p = &***a;我不确定成为三星级程序员是否在您的人生成就列表中占据重要位置。

答案 1 :(得分:3)

While it can be very useful to know that a multidimensional array is actually flat, it would usually be unidiomatic to refer to it using pointers and pointer arithmetic, because it introduces more potential for error and is harder to read than the idiomatic solution, subscript notation. Because of that, I would recommend using this:

double a[2][3][2] = {{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}};

for (int i = 0; i < 2; i++)
{
    for (int j = 0; j < 3; j++)
    {
        for (int k = 0; k < 2; k++)
        {
            cout << a[i][j][k] << endl;
        }
    }
}

答案 2 :(得分:1)

是的,多维数组总是可以被视为平面。此外,与一维数组相同,您可以说double *p = reinterpret_cast<double*>(a)double *p = &a[0][0][0]相同。

如果动态分配,多维数组可能不平坦。但那时很明显,因为分配将由你完成。