第11回:二次元配列

これまで習った「配列」は,要素が直線状に並ぶデータ形式であった。一次元データの代表的な例としては,温度や電圧などの時系列データが挙げられる。一方,画像などは二次元的にデータが並ぶ形式である。今回の演習では,二次元データをプログラム中で操作する方法を学ぶ。

例えば下に示すような成績表は,出席番号と科目という 2つの要素(行,列)から成り立っている。(一行目,一列目は,それぞれコメントで,実際のデータではない)

出席番号  語学  力学
1 65 71
2 84 83
3 74 74
4 90 90
5 87 78
6 93 95

この表に示す様なデータを,プログラム中で効率よく扱うために二次元配列を用いる。

int seiseki[6][2]; 二次元配列の宣言。[6][2]は配列の大きさ。
(行6人分,列2科目分の記憶場所を確保する)
int seiseki[6][2]={ {65, 71 } ,
                    {84, 83 } ,
                    {74, 74 } ,
                    {90, 90 } ,
                    {87, 78 } ,
                    {93, 95 }  };
宣言と同時に初期化
(括弧の対応,カンマの区切り方に注意)
seiseki[0][1] = 0; 代入。
この例では出席番号 1 番の力学の点数を 0 にする。
printf("%d¥n", seiseki[1][0]); 参照。
この例では出席番号 2 番の語学の点数が画面に表示される。

二次元配列の宣言,使用法は基本的には一次元配列と同じく

  1. 配列の添え字はそれぞれ 0 から始まる。
  2. 添え字は(配列の要素数 - 1)まで使用可能。上の例では seiseki[0][0] から seiseki[5][1] まで参照,および代入が可能。
  3. 配列名の命名規則は予約語を除く a-z, A-Z, 0-9, _ の組み合わせ。一般の変数と同じ。

である。

コンピュータの中では,二次元配列を一次元配列でも表せる。上記の例の場合,

int seiseki[12]={ 65, 71, 84, 83, 74, 74, 90, 90, 87, 78, 93, 95};

と書き表し,seiseki[行数*2 + 列] で参照すれば,同じ結果が得られる。試してみよう。


課題1

出席番号  語学   力学
1 65 71
2 84 83
3 74 74
4 90 90
5 87 78
6 93 95

(1) 各人の2科目の合計点を計算し,画面に表示する。

(2) 各科目の平均点を計算し,画面に表示する。

(3) 配列の定義を一次元配列に置き換えて,コンピュータの中で二次元配列がどのように扱われているのか,確認する。


課題2

画像データ(グラフィックス)は,二次元配列を用いる典型的な例です。通常、2値画像(”0”か”1”かで白黒を判定する画像)において”0”は”白”を、”1”は”黒”を表します。以下の表で”1”の箇所には黒を、”0”の箇所には白を画面に表示するようなプログラムを組もう。また,白黒を反転させてみよう。

int a[8][8]={ {1, 0, 0, 0, 0, 0, 0, 1 } ,
{0, 1, 0, 0, 0, 0, 1, 0 } ,
{0, 0, 1, 0, 0, 1, 0, 0 } ,
{0, 0, 0, 1, 1, 0, 0, 0 } ,
{0, 0, 0, 1, 1, 0, 0, 0 } ,
{0, 0, 1, 0, 0, 1, 0, 0 } ,
{0, 1, 0, 0, 0, 0, 1, 0 } ,
{1, 0, 0, 0, 0, 0, 0, 1 } };

一度書いた画面をクリアする命令 gcls()を加えたので,ファイル(mogla.f)を,moglaフォルダに上書き保存する。ほかにも,いろんな命令が加えられているので,興味のある人は試してみてください。


課題3

先週作成した,サインカーブ Y=sin(X) を,Y=sin(X+t)やY=sin(AX) と置き換え,t や A を変えていくとどうなるか,グラフィックスで確認してみよう。

さらに

sin

Zを色で表現することで,X - y 平面上に広がる波の様子をシミュレーションしてみよう。


課題4

初速v0=50(m/s),角度θ=45°で放たれた球が,地面に衝突し跳ね返り続ける球の軌跡をグラフィックスを用いて描きなさい。
ただし,はね返り係数e=0.8,重力加速度g=9.81(m/s2)とし,空気抵抗は無視する.また,斜方投射の式は以下を参照すること。
水平方向の距離 x=(v0×cosθ)×t ,鉛直方向の距離 y=(eJ×v0×sinθ)×t-g×t2/2 (t : 時間 ,J : 衝突回数)

投射角度を変化させると,どうなるかシミュレーションしてみよう。


参考 ビットマップファイルの取り扱いサンプル

画像データの例として,ビットマップファイルを取り上げる。ビットマップファイルは,ファイルの中身の情報(ヘッダー)と,各画素の色の値(データ)部から成り立っており,画像のファイル形式としてよく利用されている。興味のある人は,下記のサンプルをダウンロードして,確認してみてください。

サンプルプログラムサンプルビットマップファイル