概述
队列在程序设计中比较常用,可以采用链表加动态内存分配的实现队列,在控制器软件设计中部分部分产品不允许使用动态内存分配函数,如MISRA C标准(汽车产业软件可靠性协会制定)中不允许程序员使用动态内存分配。下面的软件是利用数组和宏实现队列的方法。下图是该方法在GCC上的编译输出。
基本实现
#include "stdio.h"
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
#define QUEQE_INIT(head,tail) {head=0; tail=0;}
#define QUEQE_EMPTY(head,tail) (head == tail)
#define QUEQE_FULL(head,tail,size) ((tail+1)%size == head)
#define QUEQE_PUT(name,tail,size,value) {*(name+tail)= value;tail = (tail + 1) % size;}
#define QUEQE_GET(name,head,size,value) {value = *(name+head);head = (head + 1) % size;}
#define QUEQE_LENTH(head,tail,size) ((size+tail - head)%size)
#define BUFFER_0_SIZE 16
#define BUFFER_1_SIZE 16
#define BUFFER_2_SIZE 16
u8 buff0[BUFFER_0_SIZE];
volatile u16 buff0HeadIndex;
volatile u16 buff0TailIndex;
u16 buff1[BUFFER_1_SIZE];
volatile u16 buff1HeadIndex;
volatile u16 buff1TailIndex;
u32 buff2[BUFFER_2_SIZE];
volatile u16 buff2HeadIndex;
volatile u16 buff2TailIndex;
int main(void)
{
u32 i ;
u8 temp0;
u16 temp1;
u32 temp2;
QUEQE_INIT(buff0HeadIndex, buff0TailIndex);
QUEQE_INIT(buff1HeadIndex, buff1TailIndex);
QUEQE_INIT(buff2HeadIndex, buff2TailIndex);
for(i = 0; !QUEQE_FULL(buff0HeadIndex, buff0TailIndex, BUFFER_0_SIZE); i++)
{
QUEQE_PUT(buff0, buff0TailIndex, BUFFER_0_SIZE, i);
}
while(!QUEQE_EMPTY(buff0HeadIndex, buff0TailIndex))
{
QUEQE_GET(buff0, buff0HeadIndex, BUFFER_0_SIZE, temp0);
printf("%d ", temp0);
}
printf("\nbuffer 0 ouput\n");
for(i = 0xffff; !QUEQE_FULL(buff1HeadIndex, buff1TailIndex, BUFFER_1_SIZE); i--)
{
QUEQE_PUT(buff1, buff1TailIndex, BUFFER_1_SIZE, i);
}
while(!QUEQE_EMPTY(buff1HeadIndex, buff1TailIndex))
{
QUEQE_GET(buff1, buff1HeadIndex, BUFFER_1_SIZE, temp1);
printf("%d ", temp1);
}
printf("\nbuffer 1 ouput\n");
for(i = 0xffffffff; !QUEQE_FULL(buff2HeadIndex, buff2TailIndex, BUFFER_2_SIZE); i--)
{
QUEQE_PUT(buff2, buff2TailIndex, BUFFER_2_SIZE, i);
}
while(!QUEQE_EMPTY(buff2HeadIndex, buff2TailIndex))
{
QUEQE_GET(buff2, buff2HeadIndex, BUFFER_2_SIZE, temp2);
printf("%d ", temp2);
}
printf("\nbuffer 2 ouput\n");
}
下面的代码是简化宏函数输入参数的代码
#include "stdio.h"
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
#define BUFFER_0_SIZE 16
#define BUFFER_1_SIZE 16
#define BUFFER_2_SIZE 16
struct
{
u8 head;
u8 tail;
u8 buf[BUFFER_0_SIZE];
u16 size;
} queque0;
struct
{
u16 head;
u16 tail;
u16 buf[BUFFER_1_SIZE];
u16 size;
} queque1;
struct
{
u32 head;
u32 tail;
u32 buf[BUFFER_2_SIZE];
u16 size;
} queque2;
#define QUEQE_INIT(name) {name.head=0; name.tail=0;name.size=(sizeof(name.buf)/sizeof(name.buf[0]));}
#define QUEQE_EMPTY(name) (name.head == name.tail)
#define QUEQE_FULL(name) (((name.tail+1)%name.size) == name.head)
#define QUEQE_PUT(name,value) {name.buf[name.tail]= value;name.tail = (name.tail + 1) % name.size;}
#define QUEQE_GET(name,value) {value = name.buf[name.head];name.head = (name.head + 1) % name.size;}
#define QUEQE_LENTH(name) ((name.size+name.tail - name.head)%name.size)
int main(void)
{
u32 i ;
u8 temp0;
u16 temp1;
u32 temp2;
QUEQE_INIT(queque0);
QUEQE_INIT(queque1);
QUEQE_INIT(queque2);
for(i = 0; !QUEQE_FULL(queque0); i++)
{
QUEQE_PUT(queque0, i);
}
while(!QUEQE_EMPTY(queque0))
{
QUEQE_GET(queque0, temp0);
printf("%d ", temp0);
}
printf("\nbuffer 0 ouput\n");
for(i = 0xffff; !QUEQE_FULL(queque1); i--)
{
QUEQE_PUT(queque1, i);
}
while(!QUEQE_EMPTY(queque1))
{
QUEQE_GET(queque1, temp1);
printf("%d ", temp1);
}
printf("\nbuffer 1 ouput\n");
for(i = 0xffffffff; !QUEQE_FULL(queque2); i--)
{
QUEQE_PUT(queque2, i);
}
while(!QUEQE_EMPTY(queque2))
{
QUEQE_GET(queque2, temp2);
printf("%ld ", temp2);
}
printf("\nbuffer 2 ouput\n");
}