C 양 방향 링크 의 실현
#ifndef __LIST_H
#define __LIST_H
#include <stdbool.h>
#include <pthread.h>
#define UT_BASE(TYPE) \
struct { \
TYPE *prev; \
TYPE *next; \
}
#define listSize(p) (p->listlen)
#define nodeSize(p) (p->nodelen)
#define listHead(p) (p->head)
#define listTail(p) (p->tail)
typedef struct listNode{
struct listNode *prev;
struct listNode *next;
size_t size;
char buf[];
}listNode;
typedef struct list
{
unsigned long nodelen;
listNode *head;
listNode *tail;
UT_BASE(struct list) base;
pthread_mutex_t lock;
}list;
typedef struct listmgr
{
unsigned int listlen;
list *head;
list *tail;
pthread_mutex_t lock;
}listmgr;
/*
*date:2015-08-29
*author:zhoulin
*function:create a double link list
*parameter:
* direct:if true,add list to head
*/
list *listCreate(bool direct);
int listRelease(list *lt);
listNode *listAddNode(list *lt,void *data,size_t size,bool direct);
int listDelNode(list *lt,listNode *nd);
#endif
rlist. c 코드:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rlist.h"
static listmgr *mgr=NULL;
list * listCreate(bool direct)
{
#ifdef INFO
printf(" ****************Enter listCreate(bool =%d)****************
",direct);
#endif
list *cur;
if(!mgr){
mgr=(listmgr *)malloc(sizeof(*mgr));
pthread_mutex_init(&mgr->lock,NULL);
mgr->listlen=0;
}
if(!(cur=(list *)malloc(sizeof(*cur))))
return NULL;
if(!mgr->head){
pthread_mutex_lock(&mgr->lock);
cur->base.prev=cur->base.next=NULL;
mgr->head=mgr->tail=cur;
++mgr->listlen;
pthread_mutex_unlock(&mgr->lock);
}
else{
if(direct){
cur->base.prev=mgr->head->base.prev;
cur->base.next=mgr->head;
mgr->head->base.prev=cur;
mgr->head=cur;
}
else{
cur->base.next=mgr->tail->base.next;
mgr->tail->base.next=cur;
cur->base.prev=mgr->tail;
mgr->tail=cur;
}
pthread_mutex_lock(&mgr->lock);
++mgr->listlen;
cur->nodelen=0;
cur->head=cur->tail=NULL;
pthread_mutex_unlock(&mgr->lock);
}
#ifdef INFO
printf(" ->add list =%p
",cur);
#endif
return cur;
}
int listRelease(list *lt)
{
#ifdef INFO
printf(" ****************Enter listRelease(list =%p)****************
",lt);
#endif
if(!mgr){return 1;}
if(!lt){return 1;}
if(mgr->listlen<=0){return 1;}
if(lt->base.prev&<->base.next){
lt->base.prev->base.next=lt->base.next;
lt->base.next->base.prev=lt->base.prev;
}
else if(!lt->base.prev&<->base.next){
mgr->head=lt->base.next;
mgr->head->base.prev=NULL;
}
else if(lt->base.prev&&!lt->base.next){
mgr->tail=lt->base.prev;
mgr->tail->base.next=NULL;
}
else{
mgr->head=mgr->tail=NULL;
}
lt->head=lt->tail=NULL;
lt->base.prev=lt->base.next=NULL;
listNode *nd=lt->head;
while(nd!=NULL)
{
listNode *nd_next=nd->next;
free(nd);
nd=nd_next;
}
free(lt);
lt=NULL;
pthread_mutex_lock(&mgr->lock);
--mgr->listlen;
pthread_mutex_unlock(&mgr->lock);
return 0;
}
void listPrt(listmgr *mgr)
{
#ifdef INFO
printf(" ****************Enter listPrt(listmgr =%p)****************
",mgr);
printf(" mgr->head =%p,mgr->tail =%p,mgr->listlen =%d
",mgr->head,mgr->tail,mgr->listlen);
#endif
list *lt=mgr->head;
while(lt!=NULL)
{
#ifdef INFO
printf(" current list =%p,node of len=%d,prev = %p,next =%p
",lt,lt->nodelen,lt->base.prev,lt->base.next);
#endif
listNode *lnd=lt->head;
while(lnd!=NULL)
{
#ifdef INFO
printf(" listNode =%p,prev = %p,next =%p
",lnd,lnd->prev,lnd->next);
#endif
lnd=lnd->next;
}
lt=lt->base.next;
}
}
void listDestroy(listmgr *mgr)
{
#ifdef INFO
printf(" ****************Enter listDestroy(listmgr =%p)****************
",mgr);
#endif
list *lt=mgr->head;
while(lt!=NULL)
{
list *lt_next=lt->base.next;
listNode *tmp=lt->head;
#ifdef INFO
printf(" ##free list = %p
",lt);
#endif
while(tmp!=NULL)
{
listNode *t=tmp->next;
#ifdef INFO
printf(" ->free listNode =%p
",tmp);
#endif
free(tmp);
tmp=t;
}
free(lt);
lt=lt_next;
}
}
listNode *listAddNode(list *lt,void *data,size_t size,bool direct)
{
printf(" ****************listAddNode(list =%p,data=%p,size =%d,direct =%d)****************
",lt,data,size,direct);
listNode *cur=NULL;
if(!lt||size<=0){return NULL;}
if((cur=(listNode *)malloc(sizeof(*cur)+size))==NULL){
return NULL;
}
memset((char *)&cur->buf,'\0',size);
cur->size=size;
memcpy((char *)&cur->buf,data,size);
printf(" listNode =%p,buf =%p
",cur,cur->buf);
if(!lt->head){
cur->prev=cur->next=NULL;
lt->head=lt->tail=cur;
}
else{
if(direct){
cur->prev=NULL;
cur->next=lt->head;
lt->head->prev=cur;
lt->head=cur;
}
else{
cur->next=NULL;
lt->tail->next=cur;
cur->prev=lt->tail;
lt->tail=cur;
}
}
pthread_mutex_lock(<->lock);
++lt->nodelen;
pthread_mutex_unlock(<->lock);
return cur;
}
int listDelNode(list *lt,listNode *nd)
{
if(!lt||!nd){return 1;}
return 0;
}
int main(void)
{
printf("@=1
");
list *a0=listCreate(true);
int i=100;
long x=2000;
char c='A';
listNode *n1=listAddNode(a0,(char *)&i,4,true);
listNode *n2=listAddNode(a0,(char *)&x,8,false);
listNode *n3=listAddNode(a0,(char *)&c,1,true);
printf("n1->buf =%d
",*(int *)n1->buf);
printf("n2->buf =%ld
",*(long *)n2->buf);
printf("n3->buf =%c
",*(char *)n3->buf);
listPrt(mgr);
listRelease(a0);
listPrt(mgr);
printf("@=2 head
");
list *a1=listCreate(false);
list *a2=listCreate(true);
listPrt(mgr);
listRelease(a2);
listPrt(mgr);
printf("@=2 tail
");
a2=listCreate(true);
listPrt(mgr);
listRelease(a1);
listPrt(mgr);
printf("@>2
");
a1=listCreate(false);
list *a4=listCreate(true);
list *a5=listCreate(false);
list *a6=listCreate(true);
listPrt(mgr);
listRelease(a4);
listPrt(mgr);
listDestroy(mgr);
return 0;
}
실행 결과:
[mysql@centos2 sredis]$ ./rlist
@=1
****************Enter listCreate(bool =1)****************
->add list =0x218d060
****************listAddNode(list =0x218d060,data=0x7ffdce89ff74,size =4,direct =1)****************
listNode =0x218d0c0,buf =0x218d0d8
****************listAddNode(list =0x218d060,data=0x7ffdce89ff68,size =8,direct =0)****************
listNode =0x218d0f0,buf =0x218d108
****************listAddNode(list =0x218d060,data=0x7ffdce89ff67,size =1,direct =1)****************
listNode =0x218d120,buf =0x218d138
n1->buf =100
n2->buf =2000
n3->buf =A
****************Enter listPrt(listmgr =0x218d010)****************
mgr->head =0x218d060,mgr->tail =0x218d060,mgr->listlen =1
current list =0x218d060,node of len=3,prev = (nil),next =(nil)
listNode =0x218d120,prev = (nil),next =0x218d0c0
listNode =0x218d0c0,prev = 0x218d120,next =0x218d0f0
listNode =0x218d0f0,prev = 0x218d0c0,next =(nil)
****************Enter listRelease(list =0x218d060)****************
****************Enter listPrt(listmgr =0x218d010)****************
mgr->head =(nil),mgr->tail =(nil),mgr->listlen =0
@=2 head
****************Enter listCreate(bool =0)****************
->add list =0x218d060
****************Enter listCreate(bool =1)****************
->add list =0x218d150
****************Enter listPrt(listmgr =0x218d010)****************
mgr->head =0x218d150,mgr->tail =0x218d060,mgr->listlen =2
current list =0x218d150,node of len=0,prev = (nil),next =0x218d060
current list =0x218d060,node of len=0,prev = 0x218d150,next =(nil)
****************Enter listRelease(list =0x218d150)****************
****************Enter listPrt(listmgr =0x218d010)****************
mgr->head =0x218d060,mgr->tail =0x218d060,mgr->listlen =1
current list =0x218d060,node of len=0,prev = (nil),next =(nil)
@=2 tail
****************Enter listCreate(bool =1)****************
->add list =0x218d150
****************Enter listPrt(listmgr =0x218d010)****************
mgr->head =0x218d150,mgr->tail =0x218d060,mgr->listlen =2
current list =0x218d150,node of len=0,prev = (nil),next =0x218d060
current list =0x218d060,node of len=0,prev = 0x218d150,next =(nil)
****************Enter listRelease(list =0x218d060)****************
****************Enter listPrt(listmgr =0x218d010)****************
mgr->head =0x218d150,mgr->tail =0x218d150,mgr->listlen =1
current list =0x218d150,node of len=0,prev = (nil),next =(nil)
@>2
****************Enter listCreate(bool =0)****************
->add list =0x218d060
****************Enter listCreate(bool =1)****************
->add list =0x218d1b0
****************Enter listCreate(bool =0)****************
->add list =0x218d210
****************Enter listCreate(bool =1)****************
->add list =0x218d270
****************Enter listPrt(listmgr =0x218d010)****************
mgr->head =0x218d270,mgr->tail =0x218d210,mgr->listlen =5
current list =0x218d270,node of len=0,prev = (nil),next =0x218d1b0
current list =0x218d1b0,node of len=0,prev = 0x218d270,next =0x218d150
current list =0x218d150,node of len=0,prev = 0x218d1b0,next =0x218d060
current list =0x218d060,node of len=0,prev = 0x218d150,next =0x218d210
current list =0x218d210,node of len=0,prev = 0x218d060,next =(nil)
****************Enter listRelease(list =0x218d1b0)****************
****************Enter listPrt(listmgr =0x218d010)****************
mgr->head =0x218d270,mgr->tail =0x218d210,mgr->listlen =4
current list =0x218d270,node of len=0,prev = (nil),next =0x218d150
current list =0x218d150,node of len=0,prev = 0x218d270,next =0x218d060
current list =0x218d060,node of len=0,prev = 0x218d150,next =0x218d210
current list =0x218d210,node of len=0,prev = 0x218d060,next =(nil)
****************Enter listDestroy(listmgr =0x218d010)****************
##free list = 0x218d270
##free list = 0x218d150
##free list = 0x218d060
##free list = 0x218d210
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.