您的位置:首页 > 产品设计 > UI/UE

[转]基于Cmockery和TDD开发循环Queue结构和基本操作

2010-05-03 21:50 471 查看

九月 23rd, 2009发表评论阅读评论

最基本的数据结构还包括堆(Queue),也成为FIFO;很多消息驱动的系统中都有消息队列,一般的消息队列都是一个类似Queue的结构;下面我们来实现一个基本的Queue。

一般队列都包括一个队首指针和一个队尾指针,有的还包括一个队列有效长度的记录,然后每次出队和入队时调整队列长度,不过这种结构在多线程环境中会出现同步问题; 这里考虑用队首和队尾位置来确定队列的有效长度,为此,最大有效长度为n的队列的实际有效长度为[0,n],共计n+1个可能状态,因此队列的实际最大容量应为n+1,这样做的好处是,入队线程只需调整队尾的位置记录,出队线程只需调整队首的位置记录,在出队和入队前根据2个位置来判断是否可入队和出队。

一. 考虑堆的接口

除了常规的create,destroy,is_empty,is_full,length等之外,还包括:

enqueue(Queue, Element) 在队尾加入

dequeue(Queue, Element) 队首出列

二. 基于Cmockery先编写接口测试:

#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmockery.h>
#include "./queue_array.h"

#ifdef WIN32
#pragma comment(lib, "D:/Code_Lib/cmockery/windows/cmockery.lib")
#endif

void create_test(void **state)
{
Queue qu = create(10);
assert_int_equal(length(qu), 0);
assert_false(!is_empty(qu));
destroy(qu);
}

void enqueue_test(void **state)
{
int i;

Queue qu = create(10);
for (i=0; i<10; i++)
{
enqueue(qu, i*10+1);
assert_int_equal(length(qu), i+1);
}
assert_false(!is_full(qu));
for (i=0; i<9; i++)
{
assert_int_equal(dequeue(qu), i*10+1);
assert_int_equal(length(qu), 9-i);
assert_int_equal(front(qu), i*10+11);
}
assert_int_equal(dequeue(qu), i*10+1);
assert_false(!is_empty(qu));

destroy(qu);
}

int main(int argc, char* argv[])
{
const UnitTest tests[]={
unit_test(create_test),
unit_test(enqueue_test),
};

return run_tests(tests);
};

三. 编写Queue接口:

// queue_array.h

/********************************************************************
created: 2009/09/23
created: 23:9:2009 13:35
filename: queue_array.h
file path: tdd_queue
file base: queue_array
file ext: h
author: wuyan

purpose: a queue struct which supported the reading and writting threads are separated.
*********************************************************************/

typedef int ElementType;

typedef struct TTQueue
{
int front; // the next reading element
int rear; // the last writted element
int capacity;
ElementType* data;
} TQueue;

typedef TQueue* Queue;

Queue create(int max_size);

void destroy(Queue qu);

int length(Queue qu);

int is_full(Queue qu);

int is_empty(Queue qu);

void enqueue(Queue qu, ElementType ele);

ElementType front(Queue qu);

ElementType dequeue(Queue qu);

四. 编写Queue实现:

#include "./queue_array.h"
#include "stdlib.h"

Queue create(int max_size)
{
Queue qu = malloc(sizeof(TQueue));
qu->data = malloc(sizeof(ElementType)*(max_size+1));
qu->capacity = max_size+1;
qu->front=1;
qu->rear=0;

return qu;
}

void destroy(Queue qu)
{
if (qu->data)
free(qu->data);
free(qu);
}

int length(Queue qu)
{
return ((qu->rear-qu->front+1+qu->capacity)%qu->capacity);
}

int is_full(Queue qu)
{
if (length(qu)+1 == qu->capacity)
return 1;
else
return 0;
}

int is_empty(Queue qu)
{
if (length(qu) == 0)
return 1;
else
return 0;
}

void enqueue(Queue qu, ElementType ele)
{
if (is_full(qu))
{
printf("the queue is full!/n");
return;
}

qu->rear = ((qu->rear+1) % qu->capacity);
qu->data[qu->rear] = ele;
}

ElementType front(Queue qu)
{
if (is_empty(qu))
{
printf("the queue is empty!/n");
return 0;
}
else
return qu->data[qu->front];
}

ElementType dequeue(Queue qu)
{
if (is_empty(qu))
{
printf("the queue is empty!/n");
return 0;
}
else
{
ElementType* ele = &qu->data[qu->front];
qu->front = ((qu->front+1) % qu->capacity);
return *ele;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐