キューとスタック
Copyright(C) 14May2007 coskx TNCT
複数のデータを一時的に保存する方法には2つの方法がある。1つは,先に格納したデータから先に取り出す(FIFO First In First Out)方法で,その保存場所はキューと呼ばれている。これは,通信データの一時保存や,印刷データの一時保存の方法である。もう1つは後から入れたデータから先に取り出す(FILO First In Last Out)方法で,その保存場所はスタックと呼ばれる。これは,アセンブリプログラムなどでサブルーチンコールの際の戻りアドレスを覚えておく場合や,ある種の電卓(逆ポーランド記述)などに用いられている。
1.キュー (FIFO) | |
キュー構造を実現する時にはリングバッファという手法が用いられる。配列の最後を配列の先頭にくっつけて,大きさは有限だが,無限に続く配列のように見せかける。たとえば次の例は部屋が8個しかないが,9個目のデータをしまう頃には部屋1があいているはずなので(あいていなかったら困るが,その心配は後にすることにする)部屋1にしまい,その次は部屋2にしまい,・・・を繰り返す。
次の模式図は,データを5つ入力した後,5つ取り出し,再び5つ入力して,また5つ取り出すところを見せている。
putpointerは次にデータを格納する場所を指しており,getpointerは次にデータを取り出す場所を指している。
初期状態
| ||||||||||||||||||||||||||||||||||||
データ31を格納
| ||||||||||||||||||||||||||||||||||||
データ32を格納
| ||||||||||||||||||||||||||||||||||||
データ33を格納
| ||||||||||||||||||||||||||||||||||||
データ34を格納
| ||||||||||||||||||||||||||||||||||||
データ35を格納
| ||||||||||||||||||||||||||||||||||||
データの取り出し
| ||||||||||||||||||||||||||||||||||||
データの取り出し
| ||||||||||||||||||||||||||||||||||||
データの取り出し
| ||||||||||||||||||||||||||||||||||||
データの取り出し
| ||||||||||||||||||||||||||||||||||||
データの取り出し
| ||||||||||||||||||||||||||||||||||||
データ36を格納
| ||||||||||||||||||||||||||||||||||||
データ37を格納
| ||||||||||||||||||||||||||||||||||||
データ38を格納
| ||||||||||||||||||||||||||||||||||||
データ39を格納
| ||||||||||||||||||||||||||||||||||||
データ40を格納
| ||||||||||||||||||||||||||||||||||||
データの取り出し
| ||||||||||||||||||||||||||||||||||||
データの取り出し
| ||||||||||||||||||||||||||||||||||||
データの取り出し
| ||||||||||||||||||||||||||||||||||||
データの取り出し
| ||||||||||||||||||||||||||||||||||||
データの取り出し
|
実際のプログラミングでは,
(1)データをしまう配列(グローバル変数であるが,データ格納関数とデータ取り出し関数からしか操作されない)
(2)次のデータをどこの部屋にしまうかを覚えている変数
(グローバル変数であるが,データ格納関数とデータ取り出し関数からしか操作されない)
(3)次にデータを取り出すとしたらどこの部屋から取り出すのかを覚えている変数
(グローバル変数であるが,データ格納関数とデータ取り出し関数からしか操作されない)
(4)データ格納関数
(5)データ取り出し関数
で実現される。
次のプログラムは,1つのキュー構造の例である。main()は動作確認のためである。
この例では。キューを構成する配列サイズが8であるため,キューに保存されるデータ個数が8を超えないようにしている。
List 1.1 キューの例 |
#include <stdio.h> /********************queue構造の記述のはじまり***************/ void enqueue(int var)
/*格納関数*/ int dequeue(void)
/*取り出し関数*/ int main() |
実行結果 |
31 |
次の例では。キューを構成する配列サイズが8であるが,キューに保存するデータ個数が8を超えてしまった例である。これでは正しく動作していることを保障できない。
List 1.2 動作不良のキューの例 |
#include <stdio.h> /********************queue構造の記述のはじまり***************/ void enqueue(int var)
/*格納関数*/ int dequeue(void)
/*取り出し関数*/ int main() |
実行結果 |
39 |
次のプログラムはキューサイズに対する検査を行って,保存しすぎや,取り出しすぎをチェックできるようにした例である。
List 1.3 動作チェック機能を持つキューの例 |
#include <stdio.h> /********************queue構造の記述のはじまり***************/ void enqueue(int var,int *flag) /*格納関数
flag=0:成功, 1:失敗*/ int dequeue(int *flag) /*取り出し関数
flag=0:成功, 1:失敗*/ int main()
var=dequeue(&flag); |
実行結果 |
over flow |
ここに3つの例を示したが,場合によってはList 1.3のようにチェック機能つきのキューを使うことがあるが,List 1.1のままで,キューに用いる配列サイズに余裕を持たせて使うことも多い。
2.スタック(FILO) | |
初期状態
| |||||||||||||||||||||||||||
データ31を格納
| |||||||||||||||||||||||||||
データ32を格納
| |||||||||||||||||||||||||||
データ33を格納
| |||||||||||||||||||||||||||
データ34を格納
| |||||||||||||||||||||||||||
データ35を格納
| |||||||||||||||||||||||||||
データの取り出し
| |||||||||||||||||||||||||||
データの取り出し
| |||||||||||||||||||||||||||
データの取り出し
| |||||||||||||||||||||||||||
データの取り出し
| |||||||||||||||||||||||||||
データの取り出し
| |||||||||||||||||||||||||||
データ36を格納
| |||||||||||||||||||||||||||
データ37を格納
| |||||||||||||||||||||||||||
データ38を格納
| |||||||||||||||||||||||||||
データ39を格納
| |||||||||||||||||||||||||||
データ40を格納
| |||||||||||||||||||||||||||
データの取り出し
| |||||||||||||||||||||||||||
データの取り出し
| |||||||||||||||||||||||||||
データの取り出し
| |||||||||||||||||||||||||||
データの取り出し
| |||||||||||||||||||||||||||
データの取り出し
|
List 21 スタックの例 |
#include <stdio.h> /********************stack構造の記述のはじまり***************/ void push(int var)
/*格納関数*/ int pop(void)
/*取り出し関数*/ int main() |
実行結果 |
35 34 33 32 31 40 39 38 37 36 |
次の例はスタック領域からデータがはみ出さないようにチェック機能を持ったスタックの例である。
List 22 動作チェック機能を持つスタックの例 |
#include <stdio.h> /********************stack構造の記述のはじまり***************/ void push(int var,int *flag) /*格納関数
flag=0:成功, 1:失敗*/ int pop(int *flag) /*取り出し関数
flag=0:成功, 1:失敗*/ int main()
var=pop(&flag); |
実行結果 |
over flow over flow 38 37 36 35 34 33 32 31 out of data out of data |