ふじ@メガネボーイズのメモのような日記 RSSフィード

2009-08-04

汎用的なキューをC言語で

OSの提供する機能を使わないようなローレイヤー向けの汎用キューを作ってみた。

パフォーマンスが気になる場合は剰余の計算をどうにかしようw。

データとして整数値/アドレスのどちらでも格納できること、

キュー用のメモリ領域を自由に設定できることが特徴。

(datatype.hは環境に合わせて書き換えてね)

datatype.h

#ifndef __DATATYPE_H__
#define __DATATYPE_H__

/* 型定義 */
typedef	unsigned int	UINT;	/* 符号無し整数 */
typedef	int		VP_INT;	/* voidポインタまたはint(どちらでも格納できる型で定義) */
typedef	int		ER;	/* エラーコード */

/* 定数定義 */
#ifndef NULL
#define NULL	0		/* 無効ポインタ */
#endif	/* NULL */
#define E_OK	0		/* 正常終了 */
#define E_PAR	(-17)		/* パラメータエラー */
#define E_OBJ	(-41)		/* オブジェクト状態エラー */

#endif /* __DATA_TYPE_H__ */

queue.h

#ifndef __QUEUE_H__
#define __QUEUE_H__

#include "datatype.h"

/* キュー構造体 */
typedef struct {
	VP_INT	*p_data;	/* データ配列の先頭アドレス */
	UINT	head;		/* キュー先頭データの添え字 */
	UINT	num;		/* 格納されているデータ数 */
	UINT	len;		/* キューの長さ(最大データ数) */
} QUEUE;

/* キュー初期化 */
ER queue_initialize(QUEUE *p_queue, VP_INT a_data[], UINT len);

/* エンキュー */
ER queue_enqueue(QUEUE *p_queue, VP_INT data);

/* デキュー */
ER queue_dequeue(QUEUE *p_queue, VP_INT *p_data);

#endif /* __QUEUE_H__ */

queue.c

#include "datatype.h"
#include "queue.h"

ER queue_initialize(QUEUE *p_queue, VP_INT a_data[], UINT len) {
	/* 引数が不正な場合はE_PARを返却 */
	if ( p_queue == NULL || a_data == NULL || len <= 0 ) {
		return E_PAR;
	}
	
	/* メンバーの初期値を格納 */
	p_queue->p_data = a_data;
	p_queue->head = 0;
	p_queue->num = 0;
	p_queue->len = len;
	
	/* 初期化できた場合はE_OKを返却 */
	return E_OK;
}

ER queue_enqueue(QUEUE *p_queue, VP_INT data) {
	UINT index;
	
	/* 引数が不正な場合はE_PARを返却 */
	if ( p_queue == NULL ) {
		return E_PAR;
	}
	
	/* キューが満杯の場合はエンキューせずにE_OBJを返却 */
	if ( p_queue->num >= p_queue->len ) {
		return E_OBJ;
	}
	
	/* 末尾より1つ後の格納位置を計算 */
	index = ( p_queue->head + p_queue->num ) % p_queue->len;
	
	/* キューに格納 */
	p_queue->p_data[index] = data;
	p_queue->num++;
	
	/* エンキューできた場合はE_OKを返却*/
	return E_OK;
}

ER queue_dequeue(QUEUE *p_queue, VP_INT *p_data) {
	/* 引数が不正な場合はE_PARを返却 */
	if ( p_queue == NULL || p_data == NULL) {
		return E_PAR;
	}
	
	/* キューが空の場合は何もせずにE_OBJを返却 */
	if ( p_queue->num == 0 ) {
		return E_OBJ;
	}
	
	/* 先頭データを取り出して指定されたアドレスに格納 */
	*p_data = p_queue->p_data[p_queue->head];
	
	/* 先頭の添え字を更新 */
	p_queue->head = ( p_queue->head + 1 ) % p_queue->len;
	
	/* 格納されているデータ数を更新 */
	p_queue->num--;
	
	/* デキューできた場合はE_OKを返却 */
	return E_OK;
}

ekhjqkkavpekhjqkkavp 2013/12/17 16:08 cuvzrnfhbofcpz, <a href="http://www.kxcbmwblsw.com/">soenthfoby</a> , [url=http://www.axdcokrawl.com/]yqubwljtxo[/url], http://www.mdcczuzjvs.com/ soenthfoby

ゲスト



トラックバック - http://meganeboy.g.hatena.ne.jp/fuji_ttt/20090804
リンク元