次のようにポインタを使用して配列を反復処理できる場合:
for (int *iter = arr; iter != std::end(arr); ++iter) {
// code
}
ポインターを使用して (を使用せずに) 多次元配列をどのように反復処理しますauto
か?
編集:int[][]
これは次のようなものであると想定しています{{3, 6, 8}, {2, 9, 3}, {4, 8, 2}}
配列を arr[][] として宣言した場合、それらはメモリに順番に格納されるため、可能です。できるよ:
for(int * iter = &arr[0][0]; iter != &arr[0][0] + col * row; iter++)
//...
このように試してみてはどうですか:-
const int* d = data;
for ( int i = 0; i < width; ++i )
for ( int j = 0; j < height; ++j )
for ( int k = 0; k < depth; ++k )
sum += *d++;
例えば:
constexpr size_t rowCnt = 3, colCnt = 4;
int ia[rowCnt][colCnt] = { // three elements; each element is an array of size 4
{0, 1, 2, 3}, // initializers for the row indexed by 0
{4, 5, 6, 7}, // initializers for the row indexed by 1
{8, 9, 10, 11} // initializers for the row indexed by 2
};
ループ制御変数の型に型エイリアスを使用しない:
// p points to the first array in ia
for (int (*p)[colCnt] = ia; p != ia + rowCnt; ++p) {
// q points to the first element of an array of four ints; that is, q points to an int
for (int *q = *p; q != *p + colCnt; ++q)
cout << *q << " ";
cout << endl;
}
またはautoを使用して簡単に:
for (auto p = ia; p != ia + rowCnt; ++p) {
// q points to the first element of an array of four ints; that is, q points to an int
for (auto q = *p; q != *p + colCnt; ++q)
cout << *q << " ";
cout << endl;
}
sizeof
配列が静的に割り当てられていると仮定して(コンパイル時に次元がわかっている)
for(int * iter = &arr[0][0]; iter != &arr[0][0] + sizeof(arr)/sizeof(int); iter++)
、またはiter != (int*)((void*)&arr[0][0] + sizeof(arr))
(void *)ファンであり、コンパイル時の分割が嫌いな場合は、 texasbruceの回答(申し訳ありませんがコメントできませんでした)をトリックで改善します
したがって、配列の次元を気にする必要はありません:)
たぶんこんな感じ
for (int **iter = arr; iter != std::end(arr); ++iter) {
for (int *iter2 = *iter; iter2 != std::end(*arr); ++iter2) {
// code
}
}
静的に宣言された多次元配列について単に話していると仮定すると、次のようになります。
const int ROWS = 10;
const int COLS = 20;
const int DEPTH = 30;
int array[ROWS][COLS][DEPTH]; // statically allocated array
int i = 0;
for (int row = 0; row < ROWS; ++row)
{
for (int col = 0; col < COLS; ++col)
{
for (int depth = 0; depth < DEPTH; ++depth)
{
*(*(*(array + row) + col) + depth) = i++; // do whatever with it
// is equivalent to array[row][col][depth] = i++;
}
}
}
さらにレベルが必要な場合は、ポインタ間接化のレベルを追加し続けるだけです。
または:
const int ROWS = 5;
const int COLS = 6;
const int DEPTH = 3;
int array[ROWS][COLS][DEPTH]; // statically allocated array
int* p = &array[0][0][0];
int c = 0;
for (int i = 0; i < ROWS * COLS * DEPTH; ++i, p++)
{
*p = c++;
}
静的に宣言された配列はメモリ内で連続するため、最初の要素 ( array[0][0][0]
) がベース アドレス ( ) から始まるため&array
、これは機能します。
多次元配列を動的に宣言すると、 の配列へのポインター (など) へのポインターの配列へのポインターになりますobject_type
。std::vector
またはstd::array
(コンパイル時にサイズがわかっている場合) を使用して、これを単純化できます。
これらが (少なくとも直接ではなく) 反復するためにポインターを使用するわけではありませんが、
ベクトル/配列
std::vector<std::vector<std::vector<int> > > array;
// or
//std::array<std::array<std::array<int, DEPTH>, COLS>, ROWS> array; // with some slight modifications
// fill in the vectors/arrays however you want
std::for_each(array.begin(), array.end(), [](const std::vector<std::vector<int> >& v)
{
std::for_each(v.begin(), v.end(), [](const std::vector<int>& a)
{
std::for_each(a.begin(), a.end(), [](int i)
{
std::cout << i << endl;
});
});
});