2

ASCII ワールドを作成しようとしていますが、関数間で 2D 配列を渡すことができません。これは 20 x 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;
    }
}
4

3 に答える 3

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

于 2013-05-01T14:40:34.773 に答える
2

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

編集

達成したいことを達成する別の方法 (つまり、静的配列を関数に渡す) は、それを 1 つの次元配列として渡し、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;
}

この小さな例については、ここでうまく説明されています(Duoas の投稿を参照)。

したがって、これが同様のことを行うさまざまな方法を説明することを願っています。ただし、これは非常に見栄えが悪く、おそらく最良のプログラミング手法ではありません (この方法を避けるためにあらゆることを行います。動的配列は非常に優れているため、解放することを覚えておく必要があります)。

于 2013-05-01T14:35:24.060 に答える
0

[][] 構文にはコンパイル時の定数が必要なため、宣言でパラメーターのサイズを変更する必要はありません。

文字列 world[][] に置き換えると、機能するはずです。

string[]* world を使用しない場合 (文字列の配列の配列は、実際には文字列の配列へのポインターの配列です)

これが役に立てば幸いです。私の C++ はますます錆びてきています。

于 2013-05-01T14:36:29.677 に答える