循環隊列的實現

需求描述:實現一個固定長度的字符緩存管理結構,實現字符串的寫入和讀出。

1)隊列加數據,向cb尾追加長爲length的字符串,存在putting中; 當緩衝剩餘空間remain<length時,追加長爲remain的字符串,函數返回實際有效存放到緩衝中的字符串;

2)隊列取數據,在cb中讀取長度爲length的字符串,存於getting中;當隊列存放的字符數used<length時,只讀取長爲used的字符串,讀取字符串後,隊列中相應緩衝不再使用。


特別聲明,本文源碼在VC6.0上測試通過。


#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>

// 定義隊列緩衝長度,實際長度爲SIZE-1
#define SIZE 10

// 定義數組循環隊列
typedef struct cb_s
{
 char *queue;
 unsigned long front;
 unsigned long rear;
}cb_t;

void cbInit(cb_t **cb, unsigned long size);                          // 隊列初始化函數
unsigned long cbPuts(cb_t *cb, char *putting, unsigned long length); // 隊列加數據函數
char *cbGets(cb_t *cb, unsigned long length, char *getting);         // 隊列取數據函數
void cbDestroy(cb_t *cb);                                            // 隊列釋放函數


void main(void)
{
 cb_t *pcb = NULL;
 char *putting = "a+b#c*d-e!f&g";
 char getting[SIZE] = {0};

 cbInit(&pcb, SIZE);

 printf("Test of [cbPuts] operation>>\n");
 printf("%d\n\n", cbPuts(pcb, putting, 12));

 printf("Test of [cbGets] operation>>\n");
 printf("%s\n\n", cbGets(pcb, 5, getting));

 printf("Test of [cbPuts] operation>>\n");
 printf("%d\n\n", cbPuts(pcb, putting, 4));

 printf("Test of [cbGets] operation>>\n");
 printf("%s\n\n", cbGets(pcb, 5, getting));

 printf("Test of [cbGets] operation>>\n");
 printf("%s\n\n", cbGets(pcb, 5, getting));

 cbDestroy(pcb);
}

/* 隊列初始化函數,cb爲隊列緩衝,size是緩衝大小 */
void cbInit(cb_t **cb, unsigned long size)
{
 *cb = (cb_t *)malloc(sizeof(cb_t));
 if ((NULL == *cb) || (NULL == cb))
 {
  printf("cbInit:Insufficient Memory!\n");
  exit(0);
 }

 (*cb)->queue = (char *)malloc(size * sizeof(char));
 if (NULL == (*cb)->queue)
 {
  printf("cbInit:Insufficient Memory!\n");
  exit(0);
 }

 memset((*cb)->queue, 0, size * sizeof(char));
 (*cb)->front = 0;
 (*cb)->rear  = 0;
}

/* 隊列加數據函數,向cb尾追加長爲length的字符串,存在putting中;
   當緩衝剩餘空間remain<length時,追加長爲remain的字符串,函數返回實際有效存放到緩衝中的字符串 */
unsigned long cbPuts(cb_t *cb, char *putting, unsigned long length)
{
 unsigned long index = 0;
 if ((NULL == cb) || (NULL == putting))
 {
  printf("cbPuts:Insufficient Memory!\n");
  exit(0);
 }

 if ((cb->rear +1) % SIZE == cb->front)  // 隊列已滿
 {
  printf("Queue is full!\n");
  return 0;
 }
 else                                    // 隊列未滿
 {
  for (index = 0; index < length; index++)
  {
   if ((cb->rear + 1) % SIZE != cb->front)  // 隊列未滿,逐字符入隊列
   {
    cb->rear = (cb->rear + 1) % SIZE;
    *(cb->queue + cb->rear) = *(putting + index);
   }
   else
   {
    break;  // 隊列剩餘空間<length,隊列滿時跳出循環;否則,跳過該語句
   }
  }
  return index;
 }
}

/* 隊列取數據函數,在cb中讀取長度爲length的字符串,存於getting中;
   當隊列存放的字符數used<length時,只讀取長爲used的字符串,讀取字符串後,隊列中相應緩衝不再使用 */
char *cbGets(cb_t *cb, unsigned long length, char *getting)
{
 unsigned long index = 0;

 if (NULL == cb)
 {
  printf("cbGets:Insufficient Memory!\n");
  exit(0);
 }

 if (cb->rear == cb->front)  // 隊列爲空
 {
  printf("Queue is empty!\n");
  return NULL;
 }
 else                        // 隊列非空
 {
  for (index = 0; index < length; index++)
  {
   if (cb->rear != cb->front)  // 隊列非空,逐字符出隊列
   {
    cb->front = (cb->front + 1) % SIZE;
    *(getting + index) = *(cb->queue + cb->front);
    *(cb->queue + cb->front) = 0;  // 出隊列緩存清零
   }
   else
   {
    break;  // 隊列存放字節數<length,隊列空時跳出循環;否則,跳過該語句
   }
  }
  *(getting + index) = '\0';
  return getting;
 }
}

/* 隊列釋放函數,釋放cb佔用的內存 */
void cbDestroy(cb_t *cb)
{
 if (NULL == cb)
 {
  printf("cbDestroy:Insufficient Memory/Queue isnot Existing!\n");
  exit(0);
 }
 free(cb->queue);
 cb->queue = NULL;
 free(cb);
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章