構造体のようにクラスを使う

クラスは,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
  • 引数:操作対象のオブジェクト
  • 戻り値:なし
メイン関数

キューの動作が正常であることを十分確認できるように,関数を呼び出して確かめられる内容にする.

構造体のようなクラス