简体   繁体   English

迭代多维数组

[英]Iterating over multi-dimensional arrays

Suppose I want to do something for every number in a multi-dimensional array. 假设我想为多维数组中的每个数字做一些事情。 I've found that you can get a pointer for the first number and then use use pointer addition. 我发现你可以获得第一个数字的指针然后使用use pointer添加。 For example, the following code prints the numbers 1 through 12 : 例如,以下代码打印数字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;

Is it unidiomatic to consider a multi-dimensional array as being flat in this way? 以这种方式考虑多维阵列是否平坦是不通常的吗? If so, what is the preferred way of doing it? 如果是这样,这样做的首选方式是什么? Also, is there a simpler way to write double *p = &a[0][0][0]; 还有,有一种更简单的方法可以写double *p = &a[0][0][0]; to get a pointer for the first number in a multi-dimensional array (in the same way that you can just write double *p = a; for a one-dimensional array)? 获取多维数组中第一个数字的指针(就像你可以写double *p = a;对于一维数组一样)?

Yes, a multidimensional array is guaranteed to be flat. 是的,多维数组保证是平坦的。 However, it may be best to kind this sort of thing. 但是,最好是这种事情。 If you want to flatwise iterate over a multidimensional array, I think it'd be better to introduce a range view into it: 如果你想在多维数组上进行平面迭代,我认为最好在其中引入一个范围视图:

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};
}

And simply use that one: 只需使用那个:

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

Otherwise, the only other way of declaring p is something like double *p = &***a; 否则,唯一的另一种声明p方式就像double *p = &***a; I'm not sure if becoming a three star programmer is high on your life achievement list. 我不确定成为一名三星级程序员是否在您的人生成就列表中占据重要位置。

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;
        }
    }
}

Yes, a multi-dimensional array can always be treated as flat. 是的,多维数组总是可以被视为平面。 Also, same as a one dimensional array you can say double *p = reinterpret_cast<double*>(a) which is the same as double *p = &a[0][0][0] . 此外,与一维数组相同,您可以说double *p = reinterpret_cast<double*>(a)double *p = &a[0][0][0]

A multi-dimensional array, if dynamically allocated, may not be flat. 如果动态分配,多维数组可能不平坦。 But then that would be obvious as the allocation will be done by you. 但是,这将是显而易见的,因为分配将由您完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM