LinuxC应用开发学习笔记(五)--数据结构

6、双向链表

双向链表的头文件
#ifndef LLIST_H_
#define LLIST_H_

/*百搭的数据结构*/
typedef void LLIST;
/*首部插入*/
#define LLIST_FORWARD   1
/*尾部插入*/
#define LLIST_BACKWARD  2

/*抽象出来的函数,函数类型为llist_op*/
typedef void llist_op(const void *);

/*抽象出来的函数,函数类型为llist_cmp*/
typedef int llist_cmp(const void *,const void *);

struct llist_node_st
{   
    struct llist_node_st *prev;
    struct llist_node_st *next;
    /*变长结构体的实现,做一个占位符,使用结构体类型的变量来引用*/
    char data[1];
};

typedef struct llist_head
{
    int size;
    struct llist_node_st head;
    
    int  (*insert)(struct llist_head *,const void *,int);
    
    void *(*find)(struct llist_head *,const void *,llist_cmp *);
    
    int  (*delete)(struct llist_head *,const void *,llist_cmp *);
    
    int  (*fetch)(struct llist_head *,const void *,llist_cmp *,void *);
    
    void (*travel)(struct llist_head *,llist_op *);
}LLIST;


/*双向链表的创建*/
LLIST* llist_create(int initsize);
/*双向链表的插入*/
int llist_insert(LLIST *,const void *data,int mode);
/*双向链表的查找*/
void  *llist_find(LLIST *,const void *key,llist_cmp *);
/*双向链表的删除*/
int llist_delete(LLIST *,const void *key,llist_cmp *);
/*双向链表的元素获取*/
int llist_fetch(LLIST *,const void *key,llist_cmp *,void *data);
/*双向链表的遍历*/
void llist_travel(LLIST *,llist_op *);
/*双向链表的销毁*/
void llist_destory(LLIST *);
#endif // !LLIST_H_
双向链表的C文件
#include  <stdio.h>
#include  <stdlib.h>
#include <string.h>
#include "llist.h"

/**
  * @brief  双向链表的创建
  * @param  创建大小
  * @retval 创建的双向链表的首地址
  */
LLIST* llist_create(int initsize)
{

	 /*双向链表头结点*/
    LLIST *new;
    new = malloc(sizeof(*new));
    if (new == NULL)
        return NULL;
		/*双向链表的大小*/
    new->size = initsize;
    /*初始化双向链表的前驱结点*/
    new->head.prev = &new->head;
    /*初始化双向链表的后继结点*/
    new->head.next = &new->head;
    
	 /*使用函数指针操作,函数名传递的是函数的首地址*/
	 /*给当前指针做一个赋值*/
    new->insert = llist_insert;
    
    new->delete = llist_delete;
    
    new->find   = llist_find;
    
    new->fetch  = llist_fetch;
    
    new->travel = llist_travel;
    
    return new;
}

/**
  * @brief  双向链表的插入
  * @param  链表名,插入数据,插入模式
  * @retval 双向链表的插入状态
  */
int llist_insert(LLIST *p,const void *data,int mode)
{
    struct llist_node_st *newnode;
    struct llist_node_st *ptr = p;   
    /*结构体大小再加上ptr->size*/
    newnode = malloc(sizeof(*newnode)+ptr->size);
    if (newnode == NULL)
        return -1;
   
		/*往newnode->data位置拷贝ptr->size字节的data数据*/
    memcpy(newnode->data,data,ptr->size);
    if(newnode->data == NULL)
    	   return -2;
   
	/*首部插入模式*/
    if (mode == LLIST_FORWARD)
    {
    		 /*新前驱结点的前驱结点为头结点*/
        newnode->prev = &ptr->head;
        /*新结点的后继结点为头结点的next*/
        newnode->next = ptr->head.next;   
    }
    
    /*尾部插入模式*/
    else if(mode == LLIST_BACKWARD)
    {
    		 /*新结点的前驱结点为头结点的前驱结点*/
        newnode->prev = ptr->head.prev;
        /*新结点的next指向头结点*/
        newnode->next = &ptr->head;    
    }
    /*错误*/
    else
    {
        return -3;
    }
    		/*当前结点的前驱后继等于结点本身*/
        newnode->prev->next = newnode;
       /*当前结点的后继前驱等于结点本身*/
        newnode->next->prev = newnode;
    return 0;
}

/**
  * @brief  双向链表的查找子函数
  * @param  链表起始位置,关键字,比较函数
  * @retval 无(数据类型不统一,使用万能的void,使得函数具有通用性)
  */
static struct llist_node_st *find_(struct llist_node_st *ptr,const void *key,llist_cmp*cmp)
{
    struct llist_node_st *cur;
    for (cur = ptr->head.next;cur!= &ptr->head;cur=cur->next)
    {
    		/*比较数值是否相同*/
       if(cmp(key,cur->data)==0)
        break;
    }
    return cur;
}

/**
  * @brief  双向链表的查找
  * @param  链表名
  * @retval 无(数据类型不统一,使用万能的void,使得函数具有通用性)
  */
void  *llist_find(LLIST *p,const void *key,llist_cmp *cmp)
{
		/**/
    struct llist_node_st *node;
    struct llist_node_st *ptr = p;
    node = find_(ptr,key,cmp);
    /*如果是当前的头结点*/
    if (node == &ptr->head)
        return NULL;
    return node->data;
}

/**
  * @brief  双向链表的销毁
  * @param  链表名,删除元素名,比较函数
  * @retval 删除状态
  */
int llist_delete(LLIST *p,const void *key,llist_cmp *cmp)
{
    struct llist_node_st *node;
    struct llist_node_st *ptr = p;
    /*根据key查找,使用node接收*/
    node = find_(ptr,key,cmp);
    if (node == &ptr->head)
        return -1;
    node->prev->next = node->next;
    node->next->prev = node->prev;
    /*释放node*/
    free(node);
    return 0;
}

/**
  * @brief  双向链表的内容的删除并且拿回
  * @param  链表名
  * @retval 操作状态
  */
int llist_fetch(LLIST *p,const void *key,llist_cmp *cmp,void *data)
{
    struct llist_node_st *node;
    struct llist_node_st *ptr = p;
    node = find_(ptr,key,cmp);
    /*拿到的是头结点,返回失败*/
    if (node == &ptr->head)
        return -1;
    /*脱链的过程*/
    node->prev->next = node->next;
    node->next->prev = node->prev;
    if (node != NULL)
    {
    		/*给data的ptr->size填充node->data*/
        memcpy(data,node->data,ptr->size);
    }
    free(node);
    return 0;
}

/**
  * @brief  双向链表的遍历
  * @param  链表名
  * @retval 无
  */
void llist_travel(LLIST *p,llist_op *op)
{
    struct llist_node_st *cur;
    struct llist_node_st *ptr = p;
    /*cur等于头结点的next,跳过头结点*/
    for (cur = ptr->head.next;cur!=&ptr->head;cur=cur->next)
    {
    		/*用户回调函数,程序具有通用性,用户自行编写*/
        op(cur->data);
    }
}
/**
  * @brief  双向链表的销毁
  * @param  链表名
  * @retval 无
  */
void llist_destory(LLIST *p)
{
    struct llist_node_st *cur,*next;
    struct llist_node_st *ptr = p;
    /*cur指向第一个有效结点,cur不能等于&ptr->head,如果等于说明转过了一圈*/
    for (cur = ptr->head.next;cur != &ptr->head;cur=cur->next)
    {
    		 /*next保存当前结点的下一个结点*/
        next = cur->next;
        free(cur);
    }
    /*释放头结点*/
    free(ptr);
}

P93 C语言实现C++的面向对象

双向链表的主函数

#include  <stdio.h>
#include  <stdlib.h>
#include <string.h>
#include "llist.h"

#define NAMESIZE 32
struct score_st
{
    int id;
    char name[NAMESIZE];
    int math;
    int chinese;
};

/*用户自定义的回调函数*/
void printf_s(const void *record)
{
		/*类型转换*/
    const struct score_st *r = record;
    
    printf("""%d %s %d %d \n",r->id,r->name,r->math,r->chinese);    
};

/*用户自定义的比较回调函数*/
static int id_cmp(const void *key,const void *record)
{
		/*数据类型转换*/
    const int *k = key;
    /*数据类型转换*/
    const struct score_st *r = record;
    /*返回值是一个状态*/
    return (*k-r->id);
}

/*用户自定义的回调函数,设置为字符串比较函数*/
static int name_cmp(const void *key,const void *record)
{
	 /*参数类型的转换*/
    const char*k = key;
     /*参数类型的转换*/
    const struct score_st *r = record;  
    /*字符串比较函数*/  
    return strcmp(k,r->name);
}

int main()
{
    struct score_st tmp;
    int ret;
    LLIST *handler;
    handler =  llist_create(sizeof(struct score_st));
    if (handler == NULL)
            exit(1);
            
    for (int  i = 0; i < 7; i++)
    {
        tmp.id = i;
        snprintf(tmp.name,NAMESIZE,"std%d",i);
        tmp.math = rand()%100;
        tmp.chinese = rand()%100;
        /*调用函数并且给函数传参*/
        ret = handler->insert(handler,&tmp,LLIST_BACKWARD);
        if (ret)
            exit(1);     
    }
		/*使用面向对象方式调用*/
    handler->travel(handler,printf_s);

    printf("\n\n");
	 /*测试删除函数*/
    int id = 3;
    char *del_name = "std6";
    ret = llist_delete(handler,del_name,name_cmp);
    if (ret)
        printf("llist_delete failed\n");
    llist_travel(handler,printf_s);

		/*测试find函数*/
    struct score *data;
    data = llist_find(handler,&id,id_cmp);
    if (data == NULL)
        printf("can't find !\n");
    else 
        printf_s(data); 
    llist_destory(handler);
    exit(0);
}

7、内核源码实现双向链表

双向链表的头文件
#ifndef  LINUX_LIST_H__
#define  LINUX_LIST_H__

struct list_head
{
    struct list_head *prev;
    struct list_head *next;
};

#define  LIST_HEAD_INIT(name) {&(name),&(name)}
#define LIST_HEAD(name)  struct list_head name = LIST_HEAD_INIT(name)
static inline void __list_add(struct list_head *new,
                                struct list_head *prev,
                                struct list_head *next)
{
    next->prev = new;
    new->next = next;
    new->prev = prev;
    prev->next = new;
}

static inline void list_add(struct list_head *new,struct list_head *head)
{
    __list_add(new,head,head->next);
}

#define __list_for_each(pos,head)\
    for (pos = (head)->next;pos!= (head);pos = pos->next)
    
/*
* ptr->cur;
* type->struct score_st;
* member->node
*/

#define  offsetof(TYPE,MEMBER)  ((size_t)&((TYPE *)0)->MEMBER)
#define container_of(ptr,type,member)\
    ({ (type *)((char *)ptr - offsetof(type,member));})
#define list_entry(ptr,type,member)\
        container_of(ptr,type,member)

#endif 
双向链表的主函数
#include <stdlib.h>
#include <stdio.h>
#include "list.h"

#define NAMESIZE 32

struct score_st
{
    int id;
    char name[NAMESIZE];
    struct list_head node;
    int math;
    int chinese;
};

static void printf_s(struct score_st *d)
{
    printf("%d %s %d %d\n",d->id,d->name,d->math,d->chinese);
}

int main()
{
    struct score_st *datap;
    struct list_head *cur;
    LIST_HEAD(head);
    for (int  i = 0; i < 7; i++)
    {
        datap = malloc(sizeof(*datap));
        if (datap == NULL)
            exit(1);
        datap->id = i;
        snprintf(datap->name,NAMESIZE,"stu%d",i);
        datap->math = rand()%100;
        datap->chinese = rand()%100;
    
        list_add(&datap->node,&head);
    }
        
    __list_for_each(cur,&head)
    {
        datap =  list_entry(cur,struct score_st,node);
        printf_s(datap);
    }
     __list_for_each(cur,&head)
    {
        datap =  list_entry(cur,struct score_st,node);
        if (datap->id == 5)
        {
            break;
        } 
    }
    if (cur == &head)
        printf("can't find");
    else
        printf_s(datap);
    exit(0);
}

8、栈的实现(线性表)

栈实现的头文件
#ifndef SQSTACK_H__
#define SQSTACK_H__

#define MAXSIZE 5

typedef int datatype;

typedef struct node_st
{
    datatype data[MAXSIZE];
    /*记录栈顶的位置*/
    int top;
}sqstack;
/*栈的创建*/
sqstack *st_create(void);
/*判断栈是否为空*/
int st_isempty(sqstack*);
/*入栈*/
int st_push(sqstack*,datatype *);
/*出栈*/
int st_pop(sqstack*,datatype *);
/*获取栈顶元素*/
int st_top(sqstack*,datatype *);//fetch top element;
/*栈的遍历*/
void st_travel(sqstack*);
/*栈的销毁*/
void st_destory(sqstack *);
#endif // !SQSTACK_H__
栈实现的C文件
#include <stdlib.h>
#include <stdio.h>
#include "sqstack.h"
/**
  * @brief  栈的创建
  * @param  None
  * @retval 栈的起始位置
  */
sqstack *st_create(void)
{
    sqstack *st;
    st = malloc(sizeof(*st));
    if (st == NULL)
          return NULL;
	/*配置栈顶元素为-1*/
    st->top = -1;
    return st;
}

/**
  * @brief  判断栈是否为空
  * @param  栈的起始位置
  * @retval 1表示为空,0表示非空
  */
int st_isempty(sqstack* st)
{
    return (st->top == -1);  
}

/**
  * @brief  入栈
  * @param  栈的起始位置,入栈元素
  * @retval -1表示失败,0表示成功
  */
int st_push(sqstack* st ,datatype *data)
{
	 /*栈已满*/
    if (st->top == MAXSIZE - 1)
    {
        return -1;
    }
     /*栈的下一个元素存放data*/
    st->data[++st->top]  =  *data;
    return 0;
}

/**
  * @brief  出栈
  * @param  栈的起始位置,出栈元素
  * @retval 1表示为空,0表示非空
  */
int st_pop(sqstack*st,datatype *data)
{
		/*判断栈是否为空*/
    if (st_isempty(st))
        return -1;
    /*指向栈顶的下一个元素*/
    *data = st->data[st->top --];
    return 0; 
}

/**
  * @brief  取栈顶元素
  * @param  栈的起始位置,出栈元素
  * @retval -1表示失败,0表示成功
  */
int st_top(sqstack*st,datatype *data)//fetch top element;
{
		/*判断栈是否为空*/
     if (st_isempty(st))
    {
        return -1;
    }
    *data = st->data[st->top];
    return 0;
}

/**
  * @brief  栈的遍历
  * @param  栈的起始位置
  * @retval None
  */
void st_travel(sqstack* st)
{
		/*判断栈是否为空*/
    if (st_isempty(st))
    return ;
    /*循环遍历栈内元素*/
    for (int i = 0; i <= st->top; i++)
    {
        printf("%d \n",st->data[i]);
    }
    printf("\n");
}

/**
  * @brief  栈的销毁
  * @param  栈的起始位置
  * @retval None
  */
void st_destory(sqstack * st)
{
    free(st);  
}

栈实现的主函数
#include <stdlib.h>
#include <stdio.h>
#include "sqstack.h"

int main()
{
    datatype arr[] = {19,23,45,67};
    sqstack *st;
    st = st_create();
    if (st == NULL)
        exit(1);
    /*栈的初始化*/
    for (int  i = 0; i < sizeof(arr)/sizeof(*arr); i++)
    {
        st_push(st,&arr[i]);
    }
		/*栈的遍历*/
    st_travel(st);
	  
    datatype tmp;
    while (st_pop(st,&tmp) == 0)
    {
        printf("POP: %d\n",tmp);
    }
    /*出栈测试*/
    datatype tmp = 1;
    int ret;
    ret = st_push(st,&tmp);
    if (ret != 0)
        printf("st_push failed.\n");
    else
        st_travel(st);
    st_destory(st);
}

9、栈的实现(链表)

栈实现的头文件
#ifndef STACK_H__
#define STACK_H__
#include "llist.h"

typedef LLIST STACK;
/*栈的创建*/
STACK *stack_create(int initsize);
/*入栈*/
int stack_push(STACK * ,const void*);
/*出栈*/
int stack_pop(STACK * ,void *);
/*销毁栈*/
void stack_destory(STACK *);
#endif // !STACK_H__
栈实现的C文件

#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
/**
  * @brief  栈的创建
  * @param  栈的大小
  * @retval 栈的起始地址
  */
STACK* stack_create(int initsize)
{
		/*通过链表创建栈*/
   return llist_create(initsize);
}

/**
  * @brief  入栈
  * @param  栈名,入栈内容
  * @retval 入栈的状态
  */
int stack_push(STACK *ptr ,const void*data)
{
    return llist_insert(ptr,data,LLIST_FORWARD);
}

/**
  * @brief  静态定义完全匹配函数
  * @param  任意匹配的参数1,任意匹配的参数2
  * @retval None
  */
static int always_match(const void *p1,const void *p2)
{
    return 0;
}

/**
  * @brief  出栈
  * @param  栈的起始位置,出栈元素
  * @retval 出栈状态
  */
int stack_pop(STACK *ptr ,void *data)
{
    return llist_fetch(ptr,(void *)0,always_match,data);
}

/**
  * @brief  栈的销毁
  * @param  栈的首地址
  * @retval None
  */
void stack_destory(STACK *ptr)
{
    llist_destory(ptr);
}
栈实现的主函数
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"

#define NAMESIZE 32

int ret;

struct score_st
{
    int id;
    char name[NAMESIZE];
    int math;
    int chinese;
};
/*打印函数,打印出栈的元素*/
static void  printf_s(void *record)
{
    struct score_st *r = record;
    printf("%d %s %d %d \n",r->id,r->name,r->math,r->chinese);
}

int main()
{
    STACK *st;
    
    struct score_st tmp;
    
    st =  stack_create(sizeof(struct score_st));
    if (st == NULL)
       exit(1);
    for (int i = 0; i < 7; i++)
    {   
        tmp.id = i;
        snprintf(tmp.name,NAMESIZE,"std%d",i);
        tmp.math = rand()%100;
        tmp.chinese = rand()%100;
        /*如果入栈异常*/
        if(stack_push(st,&tmp))
        			exit(1);
    }
    
    while (1)
    {
    		 
        ret =  stack_pop(st,&tmp);
        /*如果出栈异常,跳出*/
        if (ret == -1)
            break;
        printf_s(&tmp);
    }
    stack_destory(st);
    exit(0);
}

10、队列的实现(线性表)

队列实现的头文件
#ifndef QUEUE__H_
#define QUEUE__H_
#define MAXSIZE 5
typedef int datatype;

typedef struct node_st
{
    datatype data[MAXSIZE];
    int head,tail;
}queue;

/*队列的创建*/
queue *qu_create();
/*判断队列是否为空*/
int qu_isempty(queue *);
/*队列的入队*/
int qu_enqueue(queue*,datatype *);
/*队列的出队*/
int qu_dequeue(queue*,datatype *);
/*队列的遍历*/
void qu_travel(queue*);
/*队列的清除*/
void qu_clear(queue*);
/*队列的销毁*/
void qu_destory(queue *);

#endif // !QUEUE__H_
队列实现的C文件
#include <stdlib.h>
#include <stdio.h>
#include "queue.h"

/**
  * @brief  队列的创建
  * @param  None
  * @retval 队列的首地址
  */
queue *qu_create()
{
    queue*sq;
    sq = malloc(sizeof(*sq));
    if (sq == NULL)
    {
        return NULL;
    }
    sq->head = 0;
    sq->tail = 0;
    return sq;
}

/**
  * @brief  判断队列是否为空
  * @param  队列的首地址
  * @retval 1表示为空,0表示非空
  */
int qu_isempty(queue *sq)
{
    return (sq->head == sq->tail);
}

/**
  * @brief  队列的入队
  * @param  队列的首地址,入队元素
  * @retval 入队状态
  */
int qu_enqueue(queue*sq,datatype *x)
{
    if ((sq->tail+1)%MAXSIZE == sq->head)//如果尾巴取余+1等于头,那么不可以加入。
        return -1;
    /*队列的尾巴等于队列的尾巴+1 和 队列最大值取余*/
    sq->tail = (sq->tail +1) % MAXSIZE;
    /*入队元素就是待入队的元素*/
    sq->data[sq->tail] = *x;
    return 0; 
}

/**
  * @brief  队列的出队
  * @param  队列的首地址,出队元素
  * @retval 出队状态
  */
int qu_dequeue(queue*sq,datatype *x)
{
		/*判断队列是否为空*/
    if(qu_isempty(sq))
            return -1;    
    /*队列的头等于队列的头+1 和 队列最大值取余表示队列的起始位置*/
    sq->head = (sq->head+1)%MAXSIZE;
    /*出队元素就是队列的头*/
    *x = sq->data[sq->head];
    return 0;
}

/**
  * @brief  队列的遍历
  * @param  队列的首地址
  * @retval None
  */
void qu_travel(queue*sq)
{
		/*判断队列是否合法*/
    if (sq->head == sq->tail)
        return ;
    /*队列的起始位置*/
    int i = (sq->head + 1)%MAXSIZE;
    /*头部结点不等于尾部结点时*/
    while (i!=sq->tail)
    {
    		/*打印每一个结点*/
        printf("%d ",sq->data[i]);
        /*队列位置递增*/
        i = (i+1)%MAXSIZE;
    }
    /*打印最后一个结点*/
    printf("%d \n",sq->data[i]);  
}

/**
  * @brief  队列的清空
  * @param  队列的首地址
  * @retval None
  */
void qu_clear(queue*sq)
{
		/*让队列的头部指向队列的尾巴*/
    sq->head = sq->tail;
}

/**
  * @brief  队列的销毁
  * @param  队列的首地址
  * @retval None
  */
void qu_destory(queue *sq)
{
    free(sq);   
}
队列实现的主函数
#include <stdlib.h>
#include <stdio.h>
#include "queue.h"

int main()
{
    queue *sq;
    datatype arr[] = {2,3,98,12};
    int i,ret;
    /*队列的创建*/
    sq = qu_create();
    if (sq == NULL)
        exit(1);
    /*队列的初始化*/
    for (int  i = 0; i < sizeof(arr)/sizeof(*arr); i++)
    {
        qu_enqueue(sq,&arr[i]);
    }    
    /*队列的遍历*/
    qu_travel(sq);
    
    /*队列入队的测试*/
    datatype tmp = 100;
    ret = qu_enqueue(sq,&tmp);
    if (ret == -1)
        printf("queue is full!\n");
    else
        qu_travel(sq);
		/*队列的出队测试*/
    datatype tmp;
    qu_dequeue(sq,&tmp);
    printf("DEQUEUE: %d \n",tmp);
    /*队列的遍历*/
    qu_travel(sq);
    /*队列的销毁*/
    qu_destory(sq);
    exit(0);
}

11、队列的实现(链表)

链表实现的头文件
#ifndef QUEUE__H_
#define QUEUE__H_
#include "llist.h"

typedef LLIST QUEUE;
/*队列的创建*/
QUEUE *queue_create(int);
/*队列入队*/
int queue_en(QUEUE *,const void * );
/*队列出队*/
int queue_de(QUEUE *,void *);
/*队列销毁*/
void queue_destory(QUEUE *);
#endif //  QUEUE__H_
链表实现的C文件
#include <stdio.h>
#include <stdlib.h>
#include "queue.h"

/**
  * @brief  队列创建
  * @param  队列的大小
  * @retval 队列的首地址
  */
QUEUE * queue_create(int size)
{
    return llist_create(size);
}

/**
  * @brief  队列的入队
  * @param  队列的首地址,入队元素
  * @retval 入队状态
  */
int queue_en(QUEUE *ptr,const void * data)
{
    return llist_insert(ptr,data,LLIST_BACKWARD);
}

/**
  * @brief  完全匹配函数
  * @param  通用类型 p1,p2
  * @retval 0
  */
static int  alwaws_match(const void *p1 ,const void *p2)
{
    return 0;
}

/**
  * @brief  队列的出队
  * @param  队列的首地址,出队数据
  * @retval None
  */
int queue_de(QUEUE *ptr,void *data)
{
    return llist_fetch(ptr,(void*)0,alwaws_match,data);
}

/**
  * @brief  队列的销毁
  * @param  队列的首地址
  * @retval None
  */
void queue_destory(QUEUE *ptr)
{
    llist_destory(ptr);
}
链表实现的主函数
#include <stdio.h>
#include <stdlib.h>
#include "queue.h"

#define MAXSIZE 32
struct score_st
{
    int id;
    char name[MAXSIZE];
    int math;
    int chinese;
};

/*自定义打印函数,参数为通用void*类型*/
static void printf_s(void *record)
{
    struct score_st *r = record;
    printf("%d %s %d %d \n",r->id,r->name,r->math,r->chinese);
}

int main()
{
    QUEUE *qu;
    int ret;
    struct score_st tmp;
    /*队列的创建*/
    qu = queue_create(sizeof(struct score_st));
        if (qu == NULL)
            exit(1);  
    for (int  i = 0; i < 7; i++)
    {
        tmp.id = i;
        snprintf(tmp.name,MAXSIZE,"stu%d",i);
        tmp.math = rand()%100;
        tmp.chinese = rand()%100;
        
        /*判断队列入队是否发生错误*/
        if(queue_en(qu,&tmp)!=0)
            break;
    }
     
    /*队列执行出队操作*/
    while (1)
    {
        ret =  queue_de(qu,&tmp);
        if (ret == -1)
            break;
        printf_s(&tmp);
    }
    /*队列的销毁*/
    queue_destory(qu);
    exit(0);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值