C++で1次元配列を使って2次元配列をエミュレートする方法|行優先・列優先のインデックス変換を解説
はじめに
本記事では、2次元配列を1次元配列へ変換する方法について解説します。2次元配列の各要素を、どのように1次元配列へ格納すればよいのかを具体的に見ていきましょう。
ここで用意する1次元配列のサイズは、2次元配列の全要素数である「n × m」と同じになります。
プログラミングにおいて、2次元配列を1次元配列へ格納する方式は主に次の2つがあります。
- 行優先(Row Major)
- 列優先(Column Major)
行優先(Row Major)とは
行優先方式では、まず1行目の要素をすべて順番に格納し、その後に次の行へ移動していきます。C++をはじめ、CやPythonなど多くの言語では、この行優先が標準的なメモリ配置として採用されています。
n × m サイズの2次元配列において、要素のインデックスが (i, j) であるとき、行優先で1次元配列へ格納した場合のインデックスは次の式で求められます。
index = i × m + j
列優先(Column Major)とは
列優先方式では、まず1列目の要素をすべて順番に格納し、その後に次の列へ移動していきます。FortranやMATLABなど、一部の言語や環境ではこちらの列優先が採用されています。
n × m サイズの2次元配列において、要素のインデックスが (i, j) であるとき、列優先で1次元配列へ格納した場合のインデックスは次の式で求められます。
index = i + j × n
具体例で確認してみよう
入力: n = 3、m = 5、(i, j) = (0, 2)
出力:
行優先(row-major)= 2
列優先(column-major)= 6
計算過程:
行優先 = 0 × 5 + 2 = 2
列優先 = 0 + 2 × 3 = 6
2次元配列を1次元配列へ変換するC++プログラム
それでは、実際にインデックス変換を行うC++のサンプルコードを見てみましょう。
#include <iostream>
using namespace std;
int main() {
const int n = 3; // 行数
const int m = 5; // 列数
int grid[n][m] = {
{ 1, 2, 3, 4, 5},
{ 6, 7, 8, 9, 10},
{11, 12, 13, 14, 15}
};
int i = 0;
int j = 2;
// 行優先(Row Major)でのインデックス変換
int rowMajorIndex = i * m + j;
cout << "行優先で変換した場合の (0, 2) の要素のインデックス: " << rowMajorIndex << endl;
// 列優先(Column Major)でのインデックス変換
int colMajorIndex = i + j * n;
cout << "列優先で変換した場合の (0, 2) の要素のインデックス: " << colMajorIndex << endl;
return 0;
}
実行結果
行優先で変換した場合の (0, 2) の要素のインデックス: 2
列優先で変換した場合の (0, 2) の要素のインデックス: 6
まとめ
2次元配列を1次元配列へ変換する際は、行優先なら「i × m + j」、列優先なら「i + j × n」という式でインデックスを計算できます。この考え方は、画像処理におけるピクセルデータの扱いや、行列演算ライブラリの内部実装など、実際の開発現場でも広く活用されています。メモリ上のデータ配置を正しく理解することで、より効率的なプログラムを書けるようになるでしょう。
-
C++のnew演算子を使って2次元配列を動的に宣言・生成する方法
動的な2次元配列とは、基本的に「配列へのポインタ」を要素とする配列(ポインタの配列)のことです。つまり、各行が独立した1次元配列としてヒープ上に確保され、それらの先頭アドレスを格納するポインタ配列によって全体が管理されます。下図は、3×4の2次元配列のイメージです。アルゴリズムC++のnew演算子で2次元配列を動的に確保する手順は以下の通りです。Begin 配列の寸法(行数・列数)を宣言する。 new を使って 2次元配列 a[][] を動的に確保する。 配列に要素を代入する。 配列の内容を出力する。 delete でメモリを解放する。 Endサンプルコ
-
【C++】new演算子で2次元配列を動的に宣言する方法を解説
C++において、new演算子を使って2次元配列を動的に確保する方法は、メモリ管理の理解を深めるうえで重要なテクニックです。この記事では、基本的な仕組みから具体的なコード例、そして解放時の注意点までわかりやすく解説します。動的2次元配列の基本構造動的な2次元配列とは、本質的には「配列へのポインタ」を要素とするポインタ配列です。つまり、まずポインタへのポインタ(int**)の配列を確保し、その後ループ処理で各行に対応する1次元配列を個別に割り当てていくという手順になります。コード例:3×4の2次元配列を作成する#include<iostream> using namespace std