2014-05-21 49 views
0

鑑於下面的代碼,我試圖理解,如果指針操作是合法的:我可以使用指針表示多維數組嗎?

struct Foo{ 
int *temp1; 
} 

temp1目錄=> 2D陣列

struct Foo1{ 
int temp1[2][2]; 
} 

temp1目錄=> 3D陣列

struct Foo2{ 
int temp1[3][2][3]; 
} 

我使用靜態數據爲Foo1和Foo2賦值。對於如:

Foo1 f1 = 
{ 
{ 2, 4 }, 
{ 1, 3 } 
}; 

Foo2 f2 = 
{ 
    { 
     { 
      {101, 102, 103}, 
      {104, 105, 106}, 
     }, 
     { 
      {107, 108, 109}, 
      {110, 111, 112}, 
     }, 
     { 
      {113, 114, 115}, 
      {116, 117, 118}, 
     }, 
    } 
}; 

我可以從Foo1引用富數據是這樣的:

Foo f; 
f.temp1 = (int*)f1.temp1; 
for(int i = 0; i < 2; ++i) 
{ 
for(int j = 0; j < 2; ++j) 
{ 
    cout << "i " << i << " j " << j << " value: " << f.temp1[(i * 2) + j] << endl; 
} 
} 

我可以從foo2的引用富數據是這樣的:

Foo f; 
f.temp1 = (int*)f2.temp1; 
for(int i = 0; i < 3; ++i) 
{ 
for(int j = 0; j < 2; ++j) 
{ 
    for(int k = 0; k < 3; ++k) 
    { 
    cout << "i " << i << " j " << j << " k " << k << " value: " << f.temp1[(i * 3 * 2) + (j * 2) + k] << endl; 
    } 
} 
} 

從本質上講,我假設數組將被安排在連續的內存中,我可以像這樣解除引用它嗎?

+0

你有充分的理由*不*使用STD容器嗎? – Biffen

+0

@Biffen:是的。如果我使用矢量(也不行,不能做C++ 1x),我將不得不將數據複製到這些容器中,這對於這個要求來說是一個很大的禁忌。我有很多數據並將其複製到這些容器中需要很長時間,這在我的環境中是不可接受的。 – brainydexter

+0

聽起來是一個很好的理由。 :) – Biffen

回答

1

this question的回答表明答案是。假設它們是用[size1][size2][size3]表示法聲明的,多維數組的確在內存中連續佈局。

根據經驗,答案也是。考慮下面的代碼,我通過將您在問題中編寫的片段拼湊在一起編寫。

#include <stdio.h> 
#include <iostream> 
#include <string> 

using namespace std; 
struct Foo { 
    int *temp1; 
}; 

struct Foo1{ 
    int temp1[2][2]; 
}; 

struct Foo2{ 
    int temp1[3][2][3]; 
}; 


Foo1 f1 = 
{ 
    { 
     { 2, 4 }, 
     { 1, 3 } 
    } 
}; 
Foo2 f2 = 
{ 
    { 
     { 
      {101, 102, 103}, 
      {104, 105, 106}, 
     }, 
     { 
      {107, 108, 109}, 
      {110, 111, 112}, 
     }, 
     { 
      {113, 114, 115}, 
      {116, 117, 118}, 
     }, 
    } 
}; 


int main(){ 


    int* temp1 = (int*) f1.temp1; 
    for(int i = 0; i < 2; ++i) 
     for(int j = 0; j < 2; ++j) 
      cout << "i " << i << " j " << j << " value: " 
       << temp1[(i * 2) + j] << endl; 

    temp1 = (int*) f2.temp1; 
    cout << endl; 
    for(int i = 0; i < 3; ++i) 
     for(int j = 0; j < 2; ++j) 
      for(int k = 0; k < 3; ++k) 
       cout << "i " << i << " j " << j << " k " << k << " value: " 
        << temp1[(i * 3 * 2) + (j * 3) + k] << endl; 
} 

輸出:

i 0 j 0 value: 2 
i 0 j 1 value: 4 
i 1 j 0 value: 1 
i 1 j 1 value: 3 

i 0 j 0 k 0 value: 101 
i 0 j 0 k 1 value: 102 
i 0 j 0 k 2 value: 103 
i 0 j 1 k 0 value: 104 
i 0 j 1 k 1 value: 105 
i 0 j 1 k 2 value: 106 
i 1 j 0 k 0 value: 107 
i 1 j 0 k 1 value: 108 
i 1 j 0 k 2 value: 109 
i 1 j 1 k 0 value: 110 
i 1 j 1 k 1 value: 111 
i 1 j 1 k 2 value: 112 
i 2 j 0 k 0 value: 113 
i 2 j 0 k 1 value: 114 
i 2 j 0 k 2 value: 115 
i 2 j 1 k 0 value: 116 
i 2 j 1 k 1 value: 117 
i 2 j 1 k 2 value: 118 
+0

我有一個來自你引用的鏈接的問題。所以,我們不能真正使用'int **'來存儲二維數組,但是像上面提到的那樣使用單個指針? – brainydexter

+1

@brainydexter是的,這是正確的。 – merlin2011

+0

謝謝@ merlin2011 – brainydexter

1

的標準說清楚,並明確表示,答案是肯定的。見n3797 s8.3.4。有些語言很難閱讀,但最後的筆記說:

[注意:由此可見,C++中的數組存儲在行中該聲明有助於確定數組所消耗的存儲量,但在下標計算中不會播放其他部分。 - 注意]

因此,您可以通過使用簡單指針算術的計算來引用任何數組中的存儲,並且只需通過遞增指針來遍歷任何數組中的所有存儲。請注意,數組不需要打包。它們通常是,但可以在元素之間插入填充(但不在行或列之間填充額外的填充)。