2015-10-23 118 views
3

假設我想爲多維數組中的每個數做一些事情。我發現你可以得到第一個數字的指針,然後使用指針加法。例如,下面的代碼通過12輸出數字1對多維數組進行迭代

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; 

是否unidiomatic考慮多維數組以這種方式是平?如果是這樣,那麼這樣做的首選方式是什麼?另外,是否有更簡單的方法來編寫double *p = &a[0][0][0];以獲取多維數組中第一個數字的指針(與您可以只爲一維數組編寫double *p = a;一樣)?

回答

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;類似。我不確定是否成爲三星級程序員的成就列表很高。

+2

加一個用於「三星程序設計」 – vsoftco

+0

這難道不是太複雜了嗎? – Numeri

+0

@Numeri不,不是真的。 – Barry

1

是的,多維數組總是可以被視爲平坦的。此外,與一維數組相同,可以說double *p = reinterpret_cast<double*>(a)double *p = &a[0][0][0]相同。

多維數組,如果動態分配,可能不平坦。但是,那將是顯而易見的,因爲分配將由你完成。

+0

我試圖'雙* P = A;',它說'錯誤:不能轉換 '雙(*)[3] [2]' 到「雙* '在初始化double * p = a;' –

+0

對不起,我忘記了在C++中你需要投射指針類型來匹配。我相應地更新了我的回答 – jayant

+1

謝謝,'double * p = reinterpret_cast (a)'似乎有效。 –

3

雖然它可以是非常有用知道一個多維數組實際上是平的,它通常會是unidiomatic指使用指針和指針運算它,因爲它引入了更多的潛在錯誤和更難比讀慣用的解決方案,下標符號。正因爲如此,我建議使用這樣的:

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