第2回メモリ管理(4月19日)

■ 2次元配列

問題1

C言語では、2次元配列が扱いにくい。理由は、横幅の指定をプログラム中に組み込まなければならないので、自由度が低いからである。そこで、2次元配列を扱う構造体を定義しよう。

2次元配列の構造体 Array2dInt は、int を2次元配列として扱うために、int のデータ領域 buff、横サイズ int width、縦サイズ int height で構成する。この構造体のソースファイル名を array2dint.h とせよ。

問題2

Array2dInt の操作をするサブルーチン一式を、array2dint.c というソースファイルに作成せよ。以下のサブルーチンを含めることとせよ。

使用開始:array2dint_open
横サイズと縦サイズを指定し、メモリ確保とデフォルト値(0)による初期化を行い、Array2dInt 型のポインタを返す。メモリ確保に失敗したときは、エラー終了とする。
使用終了:array2dint_close
Array2dInt 型のポインタを指定し、関連領域およびこの構造体自身の領域を開放(free)する。
参照:array2dint_ref
横位置と縦位置を指定し、該当位置の int の値を返す。
記入:array2dint_set
横位置、縦位置、および、記入する値を指定し、該当位置の値を書き換える。

問題3

array2dint.h、array2dint.c、prac0201.c を用いて、下記のコンパイルト実行のできることを確認せよ。なお、prac0201.c はリンク先のものを使用し、Makefile は自分で作成せよ。

(1) コンパイル

> make prac0201
gcc -Wall -O3 -c array2dint.c
gcc -Wall -O3 -o prac0201 prac0201.c array2dint.o
>

(2) 実行

./prac0201 を実行し、キーボードから、x 位置、y 位置、値 を入力している。

> ./prac0201
3 4 9
 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
 0 0 0 9 0 0 0 0
 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
> 

■ ヒント

array2dint.h と array2dint.c の雛形
/* array2dint.h */
#include 「FILE *を使うために…」

typedef struct {
  「int のポインタ」
  「横サイズと縦サイズ」
} 「データ構造名」

Array2dInt *array2dint_open(???);
void array2dint_close(Array2dInt *);
??? array2dint_ref(Array2dInt *, int, int);
??? array2dint_set(Array2dInt *, int, int, int);
void array2dint_print(Array2dInt *, FILE *);
/* array2dint.c */
#include 「NULLや FILE* を使うために…」
#include 「malloc や free を使うために…」
#include 「構造体 Array2dInt を使うために…」

??? *array2dint_open( ??? )
{
  「Array2dInt を malloc」
  「malloc できなければ、エラー終了」
  「縦と横のサイズを考えて、int の領域を malloc」
  「malloc できなければ、エラー終了」
  「メンバ変数への代入
    (デフォルト値での初期化を忘れずに)」
  return ???
}

??? array2dint_close( ??? )
{
  「buff の領域を開放する」
  「自身の領域を開放する」
}

??? array2dint_ref( ??? )
{
  return ???->???[??? * ??? + ???];
}

??? array2dint_set( ??? )
{
  ???->???[??? * ??? + ???] = ??;
}

void array2dint_print(Array2dInt *a, FILE *fout)
{
  int i, j;
  for( j = 0; j < a->height; j += 1 ){
    for( i = 0; i < a->width; i += 1 )
      fprintf(fout," %d", array2dint_ref(a, i, j));
    fprintf(fout,"\n");
  }
}

□ 宿題(小レポート)

次回の演習開始時に集めます。


(c) Masato TOKUHISA (2007, April, 15.)