構造体のようにクラスを使う
クラスは,C言語における構造体を拡張したようなものである.そこで,まずは,スタックのデータ類をまとめて,構造体と同じ使い方でクラスを用いてみる.
始めに,スタックで「データを保持する配列」と「配列に含まれるデータ個数」を構造体でまとめたときと同様の内容とするクラスをつくる.すなわち,構造体の代わりにクラスを用いてまとめる.
C言語の構造体
struct stack
{
int volume;
int data[5];
};
Javaのクラス
class Stack
{
int volume;
int data[] = new int[5];
}
構造体の定義も,クラスの定義も,どちらとも型を定義しただけでは,中身を入れることはできない.このクラスを用いて,構造体を実体化して用いるときと同様に,実体化して,スタックのデータを入れることができるようにする.
C言語の構造体の実体化
struct stack tower1;
struct stack tower2;
Javaのクラスの実体化
Stack tower1 = new Stack();
Stack tower2 = new Stack();
Javaでは,「new」という命令を使うことで実体化することができる.この実体化をJavaでは
「インスタンス化」という.
「インスタンス」とは,実体化された,領域のことを指す.この,C言語では構造体,Javaではインスタンスを引数で受け取り,データの操作を行う関数を作成する.
配列を用いたときと異なるのは,データ操作を行う対象のオブジェクトが指定されているところである.
配列の時には,グローバルデータのように,どこからでも操作できる配列を用いていたため,引数で明示せずに配列を操作していた.今回の関数は,オブジェクトが複数あっても,引数で渡された対象を操作可能とするように,データ操作する対象を引数に持っている.そのほかは配列の時と同じである.
なお,クラス名を付ける時には,以下のことに気をつける.
- 名詞によって構成される
- クラス名の初めの文字は大文字にする
- 組み合わせた名詞の先頭を大文字にする
- シンプルで意味が分かる名前にする
- 一般的である場合を除き,略語を用いない
一般的な例:URL,HTML
C言語で構造体を用いたスタック
#include <stdio.h>
#define STACK_SIZE 5
struct stack
{
int volume = 0;
int data[5] = {0};
};
//「struct stack」の代わりに「Stack」という型で宣言する
typedef struct stack Stack;
//データ追加関数
int push(Stack *stack, int number)
{
if (stack->volume < STACK_SIZE)
{
stack->data[stack->volume] = number;
stack->volume++;
return 1;
}
else
{
printf("stack overflow\n");
return 0;
}
}
//データ取得関数
int pop(Stack *stack)
{
int value;
if (stack->volume > 0)
{
value = stack->data[stack->volume - 1];
stack->data[stack->volume - 1] = 0;
stack->volume--;
}
else
{
value = -1;
}
return value;
}
//状態表示関数
static void printStack(Stack stack)
{
printf("|");
for (int i = 0; i < STACK_SIZE; i++)
{
printf("%d",stack.data[i]);
printf("|");
}
printf("\n");
}
void main()
{
Stack tower;
push(&tower, 10); printStack(tower);
push(&tower, 20); printStack(tower);
push(&tower, 30); printStack(tower);
push(&tower, 40); printStack(tower);
push(&tower, 50); printStack(tower);
push(&tower, 60); printStack(tower);
printf("%d\n", pop(&tower)); printStack(tower);
printf("%d\n", pop(&tower)); printStack(tower);
printf("%d\n", pop(&tower)); printStack(tower);
printf("%d\n", pop(&tower)); printStack(tower);
printf("%d\n", pop(&tower)); printStack(tower);
printf("%d\n", pop(&tower)); printStack(tower);
}
Java言語で構造体のようにクラスを用いたスタック
class Stack
{
int volume;
int data[] = new int[5];
}
class Main
{
//データ追加関数
static boolean push(Stack stack,int number)
{
if(stack.volume < stack.data.length)
{
stack.data[stack.volume] = number;
stack.volume++;
return true;
}
else
{
System.out.printf("stack overflow\n");
return false;
}
}
//データ取得関数
static int pop(Stack stack)
{
int value;
if(stack.volume > 0)
{
value = stack.data[stack.volume -1];
stack.data[stack.volume -1] = 0;
stack.volume--;
}
else
{
value = -1;
}
return value;
}
//状態表示関数
static void printStack(Stack stack)
{
System.out.printf("|");
for(int i=0; i < stack.data.length; i++)
{
System.out.printf("%d",stack.data[i]);
System.out.printf("|");
}
System.out.printf("\n");
}
public static void main(String[] args)
{
Stack tower = new Stack();
push(tower,10);printStack(tower);
push(tower,20);printStack(tower);
push(tower,30);printStack(tower);
push(tower,40);printStack(tower);
push(tower,50);printStack(tower);
push(tower,60);printStack(tower);
System.out.printf("%d\n",pop(tower));printStack(tower);
System.out.printf("%d\n",pop(tower));printStack(tower);
System.out.printf("%d\n",pop(tower));printStack(tower);
System.out.printf("%d\n",pop(tower));printStack(tower);
System.out.printf("%d\n",pop(tower));printStack(tower);
System.out.printf("%d\n",pop(tower));printStack(tower);
}
}
|10|0|0|0|0|
|10|20|0|0|0|
|10|20|30|0|0|
|10|20|30|40|0|
|10|20|30|40|50|
stack overflow
|10|20|30|40|50|
50
|10|20|30|40|0|
40
|10|20|30|0|0|
30
|10|20|0|0|0|
20
|10|0|0|0|0|
10
|0|0|0|0|0|
-1
|0|0|0|0|0|
演習
「配列を用いたキュー」のプログラムを改良して,「構造体のようにクラスを使ったスタック」のように,保存するデータの配列と格納データ個数をクラスにまとめたプログラムを作成せよ.
複数のキュー領域を生成してデータを追加・取得できるように,関数の引数として操作対象とするキューを引数で指定できるようにすること.
データ構造
以下の設定をフィールドとするクラスを定義する.
- キューの容量:5個に固定
- キューに保存するデータ型:整数
- 保存データ個数:その時々の保存データ個数を覚えておく変数を用意
関数
キュー追加関数
- 関数名:enqueue
- 引数:操作対象のオブジェクト,追加する整数値
- 戻り値:追加成功(true),追加失敗(false)
キュー取得関数
- 関数名:dequeue
- 引数:操作対象のオブジェクト
- 戻り値:取り出した値.取り出すデータがないときは(-1)
キュー表示関数
- 関数名:printStack
- 引数:操作対象のオブジェクト
- 戻り値:なし
メイン関数
キューの動作が正常であることを十分確認できるように,関数を呼び出して確かめられる内容にする.