プログラミングC
第2回 演習問題

A問題(50点)

演習問題1

通常、平均値を求める場合は、全ての要素(数値)を足してから、その個数で除算する。しかし、前回までの平均値と新たな入力値から逐次その時点での平均値を求めることもできる。このような平均値の算出方法を逐次平均と呼び、プログラムの実行中にデータが次々と入力されるようなときに、入力毎逐次平均値を計算、表示させることもできる。

逐次平均は以下のような式で計算できる。
平均=(前回までの平均*前回までのデータの個数+今回のデータ)/今回までのデータの個数
  1. まず、逐次平均を求めるために、関数をdouble seqaverage(double, double, int)作成し、実行例の通りに動作するプログラムを作成せよ。
    なお、関数およびプログラム全体の仕様は以下の通りとする。
    • seqaverage関数の引数は、それぞれ新規入力されたデータ、前回までの平均値、前回までのデータの個数とする。
    • main関数内で、平均値用、入力データ用、データ個数用変数をそれぞれ 宣言し、必要に応じて初期化を済ませておく。
    • main関数内で、新規入力データをキーボードから入力した後、 関数seqaverageに必要な引数を与え、呼出し、戻り値を新たな平均値に すると共に、データの個数を+1しておく。
    • main関数で、その都度データ数と平均値を表示する
    • ctrl+d でデータ入力を終了し、最終的な平均値の表示を行う
    • 外部変数は使用しない(使用している場合は減点する)
    (提出ファイル名: prog01a.c)

  2. 次に、外部変数を用いて上記の方法で逐次平均を計算する関数void seqaverage_global(double)を作成し、これを用いて実行例の通りに動作するプログラムを作成せよ。
    なお、関数およびプログラム全体の仕様は以下の通りとする。
    • 前回までの平均値(初期値は適宜設定すること)をdouble型の外部変数avgで保持する
    • データの個数(初期値は適宜設定すること)をint型の外部変数cntで保持する
    • 関数seqaverage_globalの引数は新規入力された値とする
    • main関数でキーボードからデータの入力を受け付け、関数seqaverage_globalに引数として渡す
    • 関数seqaverage_globalは逐次平均値の計算を行い、データの個数と平均値の更新も行う
    • main関数で外部変数avgとcntを参照してデータ個数、平均値の表示を行う
    • ctrl+d でデータ入力を終了し、最終的な平均値の表示を行う
    (提出ファイル名: prog01b.c)

  3. さらに、上で作ったプログラムを改良し、外部変数の代わりに静的変数を用いて上記の方法で逐次平均を計算する関数double seqaverage_static(double)を作成し、これを用いて実行例の通りに動作するプログラムを作成せよ。
    なお、関数およびプログラム全体の仕様は以下の通りとする。
    • 関数seqaverage_staticの引数は新規入力された値とする
    • 関数seqaverage_staticの戻り値は逐次平均の計算法で求めた新しい平均値とする
    • 前回までの平均値(初期値は適宜設定すること)を関数seqaverage_staticの内部で静的変数として保持する
    • データの個数(初期値は適宜設定すること)を関数seqaverage_staticの内部で静的変数として保持する
    • main関数でもデータの個数を自動変数として保持する
    • main関数でキーボードからデータの入力を受け付け、関数seqaverage_staticに引数として渡す
    • 関数seqaverage_staticは逐次平均値の計算を行い、戻り値として新しい平均値を返す
    • main関数でデータ個数、平均値の表示を行う
    • ctrl+d でデータ入力を終了し、最終的な平均値の表示を行う
    • 外部変数は使用しない(使用している場合は減点する)
    (提出ファイル名: prog01c.c)
実行例
% ./a.out
入力データ: 2.0
データ数:1,平均:2.000000
入力データ: 4.0
データ数:2,平均:3.000000
入力データ: 6.0
データ数:3,平均:4.000000
入力データ: 8.0
データ数:4,平均:5.000000
入力データ: ^D
最終結果はデータ数4で、平均値5.000000でした
% ./a.out
入力データ: 2.2
データ数:1,平均 = 2.200000
入力データ: 3.6
データ数:2,平均 = 2.900000
入力データ: 0.6
データ数:3,平均 = 2.133333
入力データ: 7.9
データ数:4,平均 = 3.575000
入力データ: 7.7
データ数:5,平均 = 4.400000
入力データ: 4.9
データ数:6,平均 = 4.483333
入力データ: ^D
最終結果はデータ数6で、平均値4.483333でした
%
それぞれのプログラムを比較すると、自動変数のみを使用するタイプは引数が多くなり、 外部変数や静的変数を使う方は引数が1つで済む。 さらに、外部変数を使用する方は静的変数を使う場合に比べて必要な変数の種類も少なく、全体としてはシンプルな形になるはずです。 つまり、この演習問題程度の規模であれば外部変数の方が便利と言えるかもしれません。 しかし、プログラムの規模が大きくなり、複雑になるとプログラム中の どこからでもアクセスできるという外部変数の特性がかえって問題となり、安易に使用すると予想外の 動作を引き起こす原因になります。自動変数のみを使う場合や外部変数、静的変数も使う場合など、それぞれの特性と使いかたをよく把握した上で上手に使い分けるようにしてください。基本的には今後のプログラミングCの 演習や試験では、問題文中で外部変数を使うよう指示があった場合のみ 使用するようにして下さい。

B問題(50点)

演習問題2

2次元配列に0から99までの数値が乱数により格納されているものとし、 入力された数値以下の値に対して実行例のように数値の後ろに**をつけて 表示し、最後に該当する数値の個数を表示するプログラムを作成する。 実行例を参考にプログラムを完成させなさい。
(提出ファイル名: prog02.c)
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* 乱数初期設定に必要 */
#define ROW 6
#define COL 10

 
int main()
{
  int array[ROW][COL];
  int n=0,data;
  int i,j;
  /* 必要に応じて変数宣言を追加 */

  /* データ作成 */
  srand((unsigned int)time(NULL)); /* 乱数初期設定 */
  for (i=0; i<ROW; i++) {
    for (j=0; j<COL; j++) {
      array[i][j]=rand()%100; /* 0-99の乱数生成 */
    }
  }
 
  printf("数値を入力して下さい:");
  scanf("%d",&data);

  /* これ以降を作成 */



  return 0;
}
実行例
% ./a.out
数値を入力して下さい:5
 8  27  59  90  11  33   1**68  23  81 
50  52  63  73  57  63   6  57  26  75  
 9  70  11  94  71   4**92  35   2   5**  
 6  63  85  18  53  96  51   6  16  26  
87  66  30   2  39  40  17  45  97  95 
21   6  65  84  53  37  89  97  24  43  
5以下の値は3個ありました
% ./a.out
数値を入力して下さい:2
92   4  91  51  10  11  62  65  42  20  
40  20  22  71  34  64  66  95  22   3  
40  68  49  90  30  34  20  61  98  97  
84  90   6  76  41  53  39  55  18  81  
75  11  53  98  82  87  14   5  35  36  
 4  75  56   5  18  38  39  38  52  38  
2以下の値はありませんでした
%

演習問題3

外部変数を用いて、配列を操作するプログラムを書く。
(提出ファイル名: prog03.c)

会津大での評点(100点満点)と評価(A,B,C,D,F)は 以下のように対応している。

 しかし、今回の試験の点数は配点の都合により120点満点になったとする。 最終的な評点は100点満点にする必要があるので、そのための補正を行う。 つまり、素点に対して100点/120点を掛ける操作を行う。この計算では小数点以下の値が生じるので、小数点第1位で四捨五入することとし、この補正処理のためにcalib関数を作成、使用する。
 また、実行例のように、統計データとして、補正前後の平均点や評価分布も求め、 表示するものとする。

プログラムには以下の外部変数を用いる。
#define MAX_ST_NUM 50                   /* 学生数の最大値 */
#define MAX_SCORE 120                   /* 120点満点 */
int student_id[MAX_ST_NUM];             /* 学籍番号  */
int abs_score[MAX_ST_NUM];              /* 点数 (補正前) */
char abs_grade[MAX_ST_NUM];             /* 補正前の評価 (A - F) */
int rel_score[MAX_ST_NUM];              /* 点数 (補正後) */
char rel_grade[MAX_ST_NUM];             /* 補正後の評価 (A - F) */
int grade_dist[2][5];                   /* 評価の分布 [0]:補正前, [1] 補正後 */
                                        /* 例 grade_dist[0][0] 補正前の Fの人数 */
char cgrade[5]={'F','D','C','B','A'};   /* 評価(A - F) */
int num_student;                        /* 実際に成績を読み込んだ学生の数 */
double abs_ave=0.0;                     /* 平均点(補正前) */
double rel_ave=0.0;                     /* 平均点(補正後) */
main 関数および その他の関数のおおまかな構成と動作を以下に示す。
なお、必要に応じて点数から評価、 評価からcgrade配列用添字(インデックス)を求める関数を それぞれ作成し、使用するとよい。
int calib(int); /* 満点の補正を行う。内部では実数で計算し、小数点第1位で四捨五入した整数を返す */

int main()
{
  /* 標準入力から学籍番号と点数を読みこむコードをここに書く。 */

  adjust_score();  /* 点数を補正し、補正後の点数の配列に書きこむ。*/
  		          /* 補正前・補正後の各学生の評価(A~F)を決定し、それぞれ
                     平均点と評価分布を求める*/
  print_grade();   /* 補正前と後の点数と評価を表示。実行例参照 */
  print_stat();    /* 統計と評価分布を表示。フォーマットは実行例参照 */
  return 0;
}

実行例

サンプル入力ファイル(score_data.txt)はこちら
% ./a.out < score_data.txt
 ID   点数 評価 点数 評価
      (補正前)  (補正後)
-------------------------
 10001    67 B    56 C
 10002   120 A   100 A
...
(略)
 10016    64 C    53 C
-------------------------
統計
学生数 16人 補正前平均点 58.6点 補正後平均点 48.9点
評価分布
補正前 A 3 B 3 C 3 D 4 F 3 
補正後 A 1 B 2 C 5 D 3 F 5 
%

Extra問題

演習問題4

問題3について、入力データをリダイレクションを使わず、直接ファイル score_data.txtを開いて読み込み処理するプログラムに変更せよ。 さらに、評価分布表示の後に、キーボード入力で指定した補正後の評価 の該当者一覧を表示するように変更せよ。 その際、補正後の評価に対して、引数で指定した評価 (A, B, ..., F)に該当するデータを表示する関数 void grade_search(char) を追加し、使用すること。 評価該当者一覧表示のためのキーボード入力は、繰り返し入力できるようにしておき、 EOF(Ctrl+D, ^D)が入力された場合、プログラムを終了するものとする(この時、評価指定の入力の後に打鍵するリターンは読み飛ばすようにしておく必要がある。この処理を入れないと、繰り返し入力時に支障が出る)。
ヒント:次回のハンドアウトを参照してください。
(提出ファイル名: prog04.c)

実行例 (評価分布以降、それ以前は前問と同じ)

% ./a.out
(略)
評価分布
補正前 A 3 B 3 C 3 D 4 F 3 
補正後 A 1 B 2 C 5 D 3 F 5 
表示したい評価を大文字で入れてください(A-D,F): A
Aの一覧
 10002  100 A
表示したい評価を大文字で入れてください(A-D,F): C
Cの一覧
 10001   56 C
 10005   53 C
 10012   64 C
 10015   59 C
 10016   53 C
表示したい評価を大文字で入れてください(A-D,F): ^D
%

演習問題5

机の上に本を何冊か積み上げ、そこから本を取る場合、 一番最後に積んだ本を最初に取り出すことになり、 一番最初に積んだ本は最後に取り出されることになる。 このように 最後に入れたデータを最初に取り出す形式(後入れ、先出し、Last In, First Out: LIFO)のデータ構造は スタック(stack)と呼ばれ、コンピュータの基本的なデータ構造の1つである。 以下にスタックに関する基本的な用語を記す。 プログラミング入門ハンドアウトの第13回(p68-)も参照のこと。
以下の仕様を満たす関数 stackIO を用いてスタックを実現するプログラムを作成する。 関数の中身を埋めて、プログラムを完成させなさい。
「関数 stackIO の仕様」
(提出ファイル名: prog05.c)
スタックの実装にあたってはプログラミング入門ハンドアウトの第13回(p68-)を参考にすること。 ただし、ここに示した例は外部変数を用い、プッシュ(格納)とポップ(取り出し)はそれぞれ別の関数で行なっている。 今回の問題では静的変数を用いて関数内に全ての情報を格納し、プッシュ(格納)とポップ(取り出し)、そして表示も 同じ関数を用いる点が異なるので注意すること。
#include <stdio.h>
#define N 5
#define EMPTY -1
#define FULL  -2

int stackIO(int);

int main()
{
  int n, r;

  printf("スタックを実現するプログラム\n");
  printf("  正の整数値:入力値をスタックに格納する(Push)\n");
  printf("  負の整数値:スタックからデータを取り出す(Pop)\n");
  printf("  0:終了\n");
  while (1) {
    printf("整数値を入力 (正:格納(Push),負:取出(Pop),0:終了): ");
    scanf("%d", &n);
    if (n == 0) break; /* 終了 */
    r = stackIO(n); /* 格納または取出 */
    if (r > 0) printf("取出データ = %d\n", r); /* 取得データの表示 */
    else if (r == EMPTY) printf("エラー(スタックが空です)\n"); 
    else if (r == FULL ) printf("エラー(スタックが満杯です)\n"); 
    stackIO(0); /* 表示 戻り値は使用しない */
  }
  return 0;
}

/* 
[引数]
正の整数: 格納,負の整数: 取出,0: 表示
[戻り値]
格納の場合) スタックが満杯: マクロ定数 FULL,それ以外: 0
取出の場合) スタックが空: マクロ定数 EMPTY,それ以外: 取り出した値
表示の場合) 0
*/
int stackIO(int x)
{
  static int stack[N]; /* データを格納する配列 */
  static int size = 0; /* データ数 */
  /* 

    ここを作成

  */
}
実行例
% ./a.out
スタックを実現するプログラム
  正の整数値:入力値をスタックに格納する(Push)
  負の整数値:スタックからデータを取り出す(Pop)
  0:終了
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 31
size = 1 [31 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 41
size = 2 [31 41 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 59
size = 3 [31 41 59 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1
取出データ = 59
size = 2 [31 41 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 26
size = 3 [31 41 26 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 53
size = 4 [31 41 26 53 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 58
size = 5 [31 41 26 53 58 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1
取出データ = 58
size = 4 [31 41 26 53 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1
取出データ = 53
size = 3 [31 41 26 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1
取出データ = 26
size = 2 [31 41 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 97
size = 3 [31 41 97 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1
取出データ = 97
size = 2 [31 41 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1
取出データ = 41
size = 1 [31 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1
取出データ = 31
size = 0 []
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 0
% ./a.out
スタックを実現するプログラム
  正の整数値:入力値をスタックに格納する(Push)
  負の整数値:スタックからデータを取り出す(Pop)
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 1
size = 1 [1 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 2
size = 2 [1 2 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 3
size = 3 [1 2 3 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 4
size = 4 [1 2 3 4 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 5
size = 5 [1 2 3 4 5 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 6
エラー(スタックが満杯です)
size = 5 [1 2 3 4 5 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1
取出データ = 5
size = 4 [1 2 3 4 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1
取出データ = 4
size = 3 [1 2 3 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1
取出データ = 3
size = 2 [1 2 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1
取出データ = 2
size = 1 [1 ]
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1
取出データ = 1
size = 0 []
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): -1
エラー(スタックが空です)
size = 0 []
数値を入力 (正:格納(Push),負:取出(Pop),0:終了): 0
%

演習問題6

バス停で列を作ってバスを待つ場合、一番最初に並んだ人が最初にバスに乗り、 一番最後に並んだ人は最後にバスに乗ることになる。 このように最初に入れたデータを最初に取り出す(先入れ、先出し、First In, First Out: FIFO)形式のデータ構造は キュー(queue)と呼ばれ、スタック(stack)と共にコンピュータの基本的なデータ構造の1つである。 以下にキューに関する基本的な用語を記す。 プログラミング入門ハンドアウトの第13回(p70-)も参照のこと。
以下の仕様を満たす関数 queueIO を用いてキューを実現するプログラムを作成する。 関数の中身を埋めて、プログラムを完成させなさい。
「関数 queueIO の仕様」
(提出ファイル名: prog06.c)
キューの実装にあたってはプログラミング入門ハンドアウトの第13回(p70-)を参考にすること。ただし、そこで示されている例は外部変数を使い、エンキュー(格納)とデキュー(取り出し)は それぞれ enqueue, dequeue という 2 つの関数で行っている。 今回の問題では静的変数を用いて関数内に全ての情報を格納し、エンキュー(格納)とデキュー(取り出し)そして表示も同じ関数を用いている。 また、仕様の説明で触れた通り、先頭の位置、末尾の位置に加えてデータ数も変数で管理することによって、先頭位置と末尾位置が一致する場合でもキューが空なのか満杯なのかを区別できるようになり、配列の全ての要素にデータを格納できる。
#include <stdio.h>
#define N 5
#define EMPTY -1
#define FULL  -2

int queueIO(int);

int main()
{
  int n, r;

  printf("キューを実現するプログラム\n");
  printf("  正の整数値:入力値をキューに格納する(Enqueue)\n");
  printf("  負の整数値:キューからデータを取り出す(Dequeue)\n");
  printf("  0:終了\n");
  while (1) {
    printf("整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): ");
    scanf("%d", &n);
    if (n == 0) break; /* 終了 */
    r = queueIO(n); /* 格納または取出 */
    if (r > 0) printf("取出データ: %d\n", r); /* 取得データの表示 */
    else if (r == EMPTY) printf("エラー(キューが空です)\n"); 
    else if (r == FULL ) printf("エラー(キューが満杯です)\n"); 
    queueIO(0); /* 表示 戻り値(0)は使用しない */
  }
  return 0;
}

/* 
[引数]
正の整数: 格納,負の整数: 取出,0: 表示
[戻り値]
格納の場合) キューが満杯: マクロ定数 FULL,それ以外: 0
取出の場合) キューが空: マクロ定数 EMPTY,それ以外: 取り出した値
表示の場合) 0
*/
int queueIO(int x)
{
  static int queue[N]; /* データを格納する配列 */
  static int head = 0, tail = 0, size = 0; /* 先頭,末尾,データ数 */
  /* 

    ここを作成

  */
}
実行例
% ./a.out
キューを実現するプログラム
  正の整数値:入力値をキューに格納する(Enqueue)
  負の整数値:キューからデータを取り出す(Dequeue)
  0:終了
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 31
head = 0, tail = 1, size = 1 [31 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 41
head = 0, tail = 2, size = 2 [31 41 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 59
head = 0, tail = 3, size = 3 [31 41 59 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1
取出データ = 31
head = 1, tail = 3, size = 2 [41 59 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 26
head = 1, tail = 4, size = 3 [41 59 26 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 53
head = 1, tail = 0, size = 4 [41 59 26 53 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 58
head = 1, tail = 1, size = 5 [41 59 26 53 58 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1
取出データ = 41
head = 2, tail = 1, size = 4 [59 26 53 58 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1
取出データ = 59
head = 3, tail = 1, size = 3 [26 53 58 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1
取出データ = 26
head = 4, tail = 1, size = 2 [53 58 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 97
head = 4, tail = 2, size = 3 [53 58 97 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1
取出データ = 53
head = 0, tail = 2, size = 2 [58 97 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1
取出データ = 58
head = 1, tail = 2, size = 1 [97 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1
取出データ = 97
head = 2, tail = 2, size = 0 []
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 0
% ./a.out
キューを実現するプログラム
  正の整数値:入力値をキューに格納する(Enqueue)
  負の整数値:キューからデータを取り出す(Dequeue)
  0:終了
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 1
head = 0, tail = 1, size = 1 [1 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 2
head = 0, tail = 2, size = 2 [1 2 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 3
head = 0, tail = 3, size = 3 [1 2 3 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 4
head = 0, tail = 4, size = 4 [1 2 3 4 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 5
head = 0, tail = 0, size = 5 [1 2 3 4 5 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 6
エラー(キューが満杯です)
head = 0, tail = 0, size = 5 [1 2 3 4 5 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1
取出データ = 1
head = 1, tail = 0, size = 4 [2 3 4 5 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1
取出データ = 2
head = 2, tail = 0, size = 3 [3 4 5 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1
取出データ = 3
head = 3, tail = 0, size = 2 [4 5 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1
取出データ = 4
head = 4, tail = 0, size = 1 [5 ]
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1
取出データ = 5
head = 0, tail = 0, size = 0 []
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): -1
エラー(キューが空です)
head = 0, tail = 0, size = 0 []
整数値を入力 (正:格納 (Enqueue),負:取出 (Dequeue),0:終了): 0
%