1

次のコードをコンパイルしようとしています。

bool **copyBools( bool const * const * const input )
{
    bool retval[4][4] = new bool[4][4];
    for( int i=0; i<4; ++i )
    {
        for( int j=0; j<4; ++j )
        {
            retval[i][j] = input[i][j];
        }
    }
    return retval;
}

ただし、コンパイルされず、これらのエラーが発生します。最初のエラーは次のbool retval行にあり、2 番目のエラーは次の行にありますreturn

error: array must be initialized with a brace-enclosed initializer
error: cannot convert ‘bool (*)[4]’ to ‘bool**’ 

私の理解では、[][]配列は**. これは真実ではありませんか?このコードの何が問題になっていますか? 二次元配列に対して new を呼び出す適切な方法は何ですか? として返せないのはなぜ**ですか?

4

2 に答える 2

2
bool retval[4][4] = new bool[4][4];

戻り値の型はポインターです。配列変数ではなく、ポインター変数に割り当てる必要があります。

私の理解では、[][] 配列は ** と同じものでした。これは真実ではありませんか?** として返せないのはなぜですか?

いいえ、配列の減衰は再帰的ではないためです。すると、返されたポインターとしてnew bool[4][4]取得されます (ここでは最初のレベルのみが減衰しています)。bool (*) [4]

二次元配列に対して new を呼び出す適切な方法は何ですか?

これ

bool (*retval) [4] = new bool[4][4];

動作するはずです。各要素は通常どおりretval[i][j]にアクセスされますが、情報を知らない人にとっては の型がretval少し奇妙です。これは、4 つのブール値の配列へのポインターです。ただし、コンパイラは型の一部であるため長さをチェックできるため、以下の代替手段 (両方の次元が失われる) の方が安全です。ただし、この方法でも 2 番目の次元が失われます。両方の寸法を保持する場合は、 を使用しますstd::array<std::array<bool, 4>, 4>。このstd::array方法と方法の両方の注意点は、最初の次元が不明な場合にのみ使用できますが、残りのすべての次元はコンパイル時にわかっていることです。これは、配列へのポインターを宣言するためのものです。以下の方法は、コンパイル時にすべての次元が不明な場合でも使用できます。

この代替手段は、ポインターの配列を使用し、この配列内の各ポインターにブール値の配列を含浸させることです。

bool** ptrs = new bool*[4];
for (size_t i = 0; i < 4; ++i)
   ptrs[i] = new bool[4];

これにより、 として返すことができますbool**。ここでも、new bool*[4]最初のレベルで減衰し、bool**ポインターを返します。ただし、両方の次元が不明な場合、推奨される (慣用的な) 方法は、 を使用することstd::vectorです。

推奨読書: C++ で配列を使用するにはどうすればよいですか?

于 2013-10-26T02:41:46.383 に答える
0

ここではダブル ポインターを使用する必要があります。

bool** retval = new bool*[4];
for( int i=0; i<4; ++i )
{
    retval[i] = new bool[4];
    for( int j=0; j<4; ++j )
    {
        retval[i][j] = input[i][j];
    }
}

注: ここでも多次元ベクトルを使用できます。

于 2013-10-26T02:43:41.250 に答える