2011-05-25 63 views
1

就像問題所說,我試圖將多維數組傳遞給一個函數,以將其打印到工程項目的文件中。數據輸入的格式不能改變,所以請不要建議我只是輸入它作爲不同的數據類型。如何將未知大小的多維數組傳遞給使用C++中的指針的函數?

這個特殊的函數預期了一個二維數組(儘管在這個數組之後我有其他三個維度的數組),在運行時間之前什麼都不知道數組的大小。我知道我必須使用指針來分別指向數組的每一行,但我不知道將它傳遞給函數的語法是什麼。在下面的代碼中,所討論的數組是'block'。主要功能只是我嘗試使其工作的一個小測試示例:

#include<fstream> 
using namespace std; 

void of_write_blocks(string filename, string block_type[], int **block, 
      int grid[][3], string grade_type[], int grade[][3], int n_blocks, int m[]) 
{ 
    ofstream file_out(filename.c_str(),ios::app); 
    file_out<<"\nblocks\n(\n"; 

    for(int i=0;i<n_blocks;++i) { 
      file_out<<" "<<block_type[i]<<" ("; 
        for(int j=0;j<m[i];++j) 
          file_out<<block[i][j]<<" "; 
      file_out<<") ("; 
      file_out<<grid[i][0]<<' '<<grid[i][1]<<' '<<grid[i][2]<<") "; 
      file_out<<grade_type[i]<<" ("; 
      file_out<<grade[i][0]<<' '<<grade[i][1]<<' '<<grade[i][2]<<")\n"; 
    } 
    file_out<<");\n"; 
} 


//testing example: 
int main() 
{  
    int block[6][9]; 
    for(int i=0; i<6;++i) 
      for(int j=0; i<9;++j) 
        block[i][j] = i*j; 

    int grid[6][3]; 
    for(int i=0; i<6;++i) 
      for(int j=0; i<3;++j) 
        block[i][j] = i*j; 


    int grade[6][3]; 
    for(int i=0; i<6;++i) 
      for(int j=0; i<3;++j) 
        block[i][j] = i*j; 

    string grade_type[6] = {"simpleGrading"}; 
    string block_type[6] = {"hex"}; 
    int m[6] = {8}; 
    int n_blocks = 6; 

    of_write_blocks("name",block_type,block,grid,grade_type,grade,n_blocks,m); 
}  

任何幫助表示讚賞!

+1

在過去的25年中,我從來沒有,一次也沒有,只好用一個多維數組。我錯過了什麼嗎? – 2011-05-25 19:04:56

+0

@Neil Butterworth嘗試在三個維度上解決最大連續子序列問題。我用std :: vectors在C++中實現了它,它需要4維數組。 – Arlen 2011-05-25 19:20:34

+0

@ user1344784夠公平 - 聽起來像是我和我的各種僱主對解決問題毫無興趣的問題。但是如果我要解決這些問題,我想我會使用一種語言,其中MDAs是一流的對象,比如說FORTRAN,在這個問題領域中,這幾乎可以肯定比C++更高效。 – 2011-05-25 19:25:44

回答

5

你不行。多維數組是語法糖,並直接編譯到對數組進行操作的代碼中,該數組是單個內存塊。尺寸不會作爲參數或類似的東西作爲數組的一部分傳遞到函數中,因爲這是在例如Java或C#。

如果您需要函數中數組的維數,那麼您只需要接受指向數組第一個元素的指針和維數,然後進行乘法和相加操作即可自己獲得正確的索引。

或者,使用類似於std::vector<std::vector<block>>的東西,它將尺寸作爲對象的一部分傳遞,而不是內置數組。

+0

好的軟件,尺寸輸入到其中有很大幫助的功能。我不知道如何將一個數組傳遞給函數,並將函數作爲一個指針。你能給我一個簡單的例子嗎? – 2011-05-25 18:59:36

+0

有作爲'的std ::陣列'沒有這樣的事,你忘了尺寸參數。 – fredoverflow 2011-05-25 19:01:02

+0

@Fred:哎呀。固定。你可以做用'性病的大小的方法模板:: array'是一個尺寸參數,但是這可能不是一個好主意.... – 2011-05-25 19:16:04

2

如果您安裝了Boost,請檢查Boost Multi-Array

+0

閱讀。他不能改變數據類型。 – Arlen 2011-05-25 21:25:08

+0

@ user1344784:對不起,我不明白你的評論。你能突出你的評論和我的建議之間的聯繫嗎?謝謝。 – yasouser 2011-05-26 02:15:31

+0

OP說他不能改變數據類型,那麼爲什麼你推薦Boost Multi-Array? – Arlen 2011-05-26 22:39:14

0

爲了清楚起見,我從您的示例中刪除了所有不相關的代碼。

#include <iostream> 
#include <fstream> 

using namespace std; 

void of_write_blocks(int **block, int bh, int bw){ 

    for(int i = 0; i < bh; ++i) 
    for(int j = 0; j < bw; ++j) 
     cout << block[i][j] << " "; 
    cout << endl; 
} 

int main(){  

    int bh, bw; 
    cin >> bh >> bw; 

    int** block; 
    block = new int*[bh]; 
    for(int k = 0; k < bh; k++) 
    block[k] = new int[bw]; 

    // initialize the array 
    for(int i = 0; i < bh; i++) 
    for(int j = 0; j < bw; j++) 
     block[i][j] = (i*bw) + j; 

    of_write_blocks(block, bh, bw); 
}  

主要我們正在創建一個二維數組並初始化它。然後我們將它傳遞給of_write_block,它打印數組。那是你想要做的嗎?

+0

這裏的問題是數組的大小在運行時間之前是未知的,所以將它們聲明爲常量是行不通的。該函數需要將輸入作爲數組接受,並將維作爲局部整數直接輸入到函數調用中,而不是全局常量。 – 2011-05-25 20:37:40

+0

@Mike N.數組大小可以是動態的。我改變了代碼以反映這一點。就數組大小而言,您必須將大小傳遞給函數,如示例中所示。沒有其他方式知道尺寸。 – Arlen 2011-05-25 20:46:21

0

爲什麼不能使用數組的引用。見下面的例子:

char c[10]; 
int i[10][20]; 
double d[10][20][30]; 

包裝功能是這樣的:

template<typename T, int SIZE> 
void Array (T (&a)[SIZE]) 
{} 
template<typename T, int SIZE1, int SIZE2> 
void Array (T (&a)[SIZE1][SIZE2]) 
{} 
template<typename T, int SIZE1, int SIZE2, int SIZE3> 
void Array (T (&a)[SIZE1][SIZE2][SIZE3]) 
{} 

這僅僅是一個例子來說明,這將優雅接收陣列而沒有任何複製的語法,並且還避免混亂指針。另外,如果您知道您將僅使用int,那麼只需刪除類型名稱並明確提及int即可。即

template<int SIZE> 
void Array (int (&a)[SIZE]); // explicitly mention int 
相關問題