2013-05-01 403 views
2

我想創建一個ASCII世界,但是我無法在函數之間傳遞二維數組。這是一個20×20的陣列,我想隨意放置房屋。這個數組不會像我想要的那樣通過,我的教程告訴我全局變量是邪惡的,所以沒有這些的解決方案會很好。將二維數組傳遞到函數

using namespace std; 

void place_house(const int width, const int height, string world[width][length]) 
{ 
    int max_house = (width * height)/10; //One tenth of the map is filled with houses 
    int xcoords = (0 + (rand() % 20)); 
    int ycoords = (0 + (rand() % 20)); 
    world[xcoords][ycoords] = "@"; 
} 

int main(int argc, const char * argv[]) 
{ 
    srand((unsigned)time(NULL)); 
    const int width = 20; 
    const int height = 20; 
    string world[width][height]; 
    string grass = "."; 
    string house = "@"; 
    string mountain = "^"; 
    string person = "Å"; 
    string treasure = "$"; 
    //Fill entire world with grass 
    for (int iii = 0; iii < 20; ++iii) { 
     for (int jjj = 0; jjj < 20; ++jjj) { 
      world[iii][jjj] = "."; 
     } 
    } 
    place_house(width, height, world); 
    for (int iii = 0; iii < 20; ++iii) { 
    for (int jjj = 0; jjj < 20; ++jjj) { 
     cout << world[iii][jjj] << " "; 
     } 
     cout << endl; 
    } 
} 
+1

如果數組中的每個字符串只包含一個字符,則應該使用'char'的二維數組,而不是'string'的二維數組。 – 2013-05-01 14:44:30

回答

3

嘗試通過string **代替string[][]

所以,你的函數應該聲明如下:

void place_house(const int width, const int height, string **world) 

,然後你訪問陣列,通常的方式。

請記住正確處理邊界(可能要將它們與數組一起傳遞)。


編輯:

這是你將如何實現你需要的東西:

#include <string> 
#include <iostream> 
using namespace std; 

void foo (string **bar) 
{ 
    cout << bar[0][0]; 
} 

int main(void) 
{ 
    string **a = new string*[5]; 
    for (int i = 0 ; i < 5 ; i ++) 
     a[i] = new string[5]; 

    a[0][0] = "test"; 

    foo(a); 

    for (int i = 0 ; i < 5 ; i ++) 
     delete [] a[i]; 
    delete [] a; 
    return 0; 
} 

編輯

達到你想要達到什麼樣的另一種方式(即通過靜態數組到函數)是將它作爲一個二維數組傳遞,然後使用類似C的方式訪問它。

實施例:

#include <string> 
#include <iostream> 
using namespace std; 

void foo (string *bar) 
{ 
    for (int r = 0; r < 5; r++) 
    { 
     for (int c = 0; c < 5; c++) 
     { 
      cout << bar[ (r * 5) + c ] << " "; 
     } 
     cout << "\n"; 
    } 
} 

int main(void) 
{ 
    string a[5][5]; 
    a[1][1] = "test"; 
    foo((string*)(a)); 
    return 0; 
} 

該小例子是很好的描述here(見Duoas交)。

所以我希望這將描述做類似事情的不同方式。然而,這看起來相當醜陋,可能不是最好的編程實踐(我會盡一切努力避免這樣做,動態數組相當不錯,你只需要記住釋放它們)。

+0

謝謝!但現在它說這沒有匹配的功能:\t place_house(width,height,world); – Lemonizer 2013-05-01 14:41:52

+2

這不起作用,因爲傳遞的參數是一個二維數組,但這會將該參數更改爲指向指針的指針,並且不能將二維數組轉換爲指向指針的指針。人們可以改變數組,但是這需要額外的分配和指針分配,並且是浪費和麻煩的。 – 2013-05-01 14:46:30

+0

@EricPostpischil那麼我怎樣才能使它工作沒有任何問題? – Lemonizer 2013-05-01 14:48:53

0

您不需要在聲明中調整參數的大小,也不需要因爲[] []語法需要編譯時間常量。

用字符串world [] []替換,它應該工作。

如果它沒有再使用字符串[] *世界(字符串數組的數組實際上是一個指針數組,字符串數組)

我希望這可以幫助,我的C++正變得越來越生疏。

+0

是否這樣? 無效place_house(const int的寬度,const int的高度,串世界[] []) 並使用該 place_house調用(寬度,高度,世界) 這不起作用 – Lemonizer 2013-05-01 14:40:03

+0

你是什麼意思「不工作「?不編譯或執行不好? – Waltika 2013-05-14 19:38:16

2

由於您的陣列已經編譯時已知的尺寸,你可以使用模板來檢測這樣的:

template <std::size_t W, std::size_t H> 
void place_house(string (&world)[W][H]) 
{ 
    int max_house = (W * H)/10; //One tenth of the map is filled with houses 
    int xcoords = (0 + (rand() % 20)); 
    int ycoords = (0 + (rand() % 20)); 
    world[xcoords][ycoords] = "@"; 
} 

// ... 

place_house(world); // Just pass it 

注意,這招不會與動態分配數組作品。在這種情況下,你應該使用類似std::vector的東西。

+0

我總是有一些感覺(這可能是錯誤的),做的事情C++方式產生漂亮的代碼,但當涉及到健壯性類似C的解決方案要快得多... – Greg0ry 2013-05-01 15:49:30

+0

@ Greg0ry,_「much」_?不要這樣想。另外,我有一條規則:_「不要混用C和C++。」_ – soon 2013-05-01 15:59:13