C语言设备信息的链表,实现增加,删除,修改节点值

链表用来实现存储设备在线信息查询,用于设备的增加删除修改

DevList.c 


#include <stdio.h>
#include "DevList.h"
#include <assert.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>


void SListInit(SList*s) {
 assert(s);
 s->_pHead = NULL;
}
PNode BuySListNode(SDataType data ,DevInfo devinfo )
{ 
    PNode p; 
	p= (PNode)malloc(sizeof(Node)); 
	if (p == NULL) {
		return NULL;
	}
	p->_data=data;
	p->_devinfo.id =data;
	memcpy(p->_devinfo.sn ,devinfo.sn,16);
	p->_devinfo.timestamp = devinfo.timestamp ;
	p->_PNext=NULL; 
	return p;
}


PNode buyslistnode(SDataType data) {
	PNode newnode = (PNode)malloc(sizeof(Node));
	if (newnode == NULL) {
		return NULL;
	}
	newnode->_data = data;
	newnode->_PNext = NULL;
	return newnode;
}

//尾插
void SListPushBack(SList* s, SDataType data ,DevInfo _devinfo ) {
 //找链表最后一个节点
 assert(s);
 PNode pNewNode = BuySListNode(data,_devinfo);
 if (s->_pHead == NULL) {//链表没有节点的情况
  s->_pHead = pNewNode;
 }
 else {
  PNode pCur = s->_pHead;
  while (pCur->_PNext) {
   pCur = pCur->_PNext;
  }
  //让最后一个节点指向新节点
  pCur->_PNext = pNewNode;
 }
}
//尾删除
void SListPopBack(SList* s) {
 assert(s);
 if (s->_pHead == NULL) {//链表中没有节点
  return;
 }
 else if (s->_pHead->_PNext == NULL) {//只有一个节点
  free(s->_pHead);
  s->_pHead = NULL;
 }
 else {                           //多个节点
  PNode pCur = s->_pHead;
  PNode pPre = NULL;
  while (pCur->_PNext) {
   pPre = pCur;
   pCur = pCur->_PNext;
  }
  free(pCur);
  pPre->_PNext = NULL;
 }
}
//头插
void SListPushFront(SList* s, SDataType data ,DevInfo _devinfo) {
 assert(s);
 PNode pNewNode = BuySListNode(data,_devinfo);
 if (s->_pHead == NULL) {//链表为空
  s->_pHead = pNewNode;
 }
 else {
  pNewNode->_PNext = s->_pHead;
  s->_pHead = pNewNode;
 }
}
//头山
void SListPopFront(SList* s) {
 assert(s);
 if (s->_pHead == NULL) {//链表为空
  return;
 }
 else if (s->_pHead->_PNext == NULL) {//只有一个节点
  free(s->_pHead);
  s->_pHead = NULL;
 }
 else {
  PNode pCur = s->_pHead;
  s->_pHead = pCur->_PNext;
  free(pCur);
 }
}
void SListInsert(PNode pos, SDataType data ,DevInfo _devinfo) {
 PNode pNewNode = NULL;
 if (pos == NULL) {
  return;
 }
 pNewNode = BuySListNode(data,_devinfo);
 
 pNewNode->_PNext = pos->_PNext;
 pos->_PNext = pNewNode;
}
//查找
PNode SListFind(SList* s, SDataType data) {
 assert(s);
 PNode pCur = s->_pHead;
 while (pCur) {
  if (pCur->_data == data) {
   return pCur;
  }
  pCur = pCur->_PNext;
 }
 return NULL;
}
//查找某个字符串是否相等
PNode SListFindSn(SList* s, char* data) {
 assert(s);
 PNode pCur = s->_pHead;
 while (pCur) {
  if (0 == memcmp(pCur->_devinfo.sn ,data, 16)) {
   return pCur;
  }
  pCur = pCur->_PNext;
 }
 return NULL;
}
//修改节点的值
SList*  SListModifyTimestamp(SList* s, SDataType data ,long long timestamp) {
 assert(s);
 
 PNode pCur = s->_pHead;
 while (pCur) {
  if (pCur->_data == data) {
  	pCur->_devinfo.timestamp = timestamp ;
   return s;
  }
  pCur = pCur->_PNext;
 }
 return NULL;
}

//遍历
void SListAll(SList *s)
{
    PNode p_mov= s->_pHead;
    while(p_mov!=NULL)//条件为当前节点,遍历时主要显示当前节点
    {
      //  printf("%d %d %s\n",p_mov->_data  ,p_mov->score,p_mov->name);
        p_mov=p_mov->_PNext;
    }
}

//删除给定pos位置的节点。
void SListErase(SList* s, PNode pos) {
 assert(s);
 if (pos == NULL || s->_pHead == NULL) {
  return;
 }
 if (pos== s->_pHead) {
  s->_pHead = pos->_PNext;
 }
 else {
  PNode pPrePos = s->_pHead;
  while (pPrePos&&pPrePos->_PNext != pos) {
   pPrePos = pPrePos->_PNext;
  }
  pPrePos->_PNext = pos->_PNext;
 }
 free(pos);
}

void SListRemove(SList*s, SDataType data) {
 assert(s);
 if (s->_pHead == NULL) {
  return;
 }
 PNode pPre = NULL;
 PNode pCur = s->_pHead;
 while (pCur) 
 {
	  if (pCur->_data == data) 
	  	{
			   if (pCur == s->_pHead) {         //要删除的是第一个位置的节点
			    s->_pHead = pCur->_PNext;
			   }
			   else {
			    pPre->_PNext = pCur->_PNext;      //其它位置的情况,让前一个节点指向其后一个节点
			   }
	   free(pCur);
	   return;
	  }
	  else {
	   	 pPre = pCur;
	  	 pCur = pCur->_PNext;
	  }
 }
}

int SListSize(SList* s) {            //获取链表有效节点的个数
 assert(s);
 int count = 0;
 PNode pCur = s->_pHead;
 while (pCur) {
  count++;
  pCur = pCur->_PNext;
 }
 return count;
}

int SListEmpty(SList* s) {              //检测链表是否为空
 assert(s);
 if (s->_pHead == NULL) {
  return -1;
 }
 return 0;
}

void SListClear(SList* s) {             //清空链表
 assert(s);
 if (s->_pHead == NULL) {
  return;
 }
 PNode pCur = s->_pHead;
 while (pCur->_PNext) {    //循环清空链表中的节点
  PNode Tmp = pCur->_PNext;
  free(pCur);
  pCur = Tmp;
 }
 if (pCur) {      //清空最后一个节点
  free(pCur);
  pCur = NULL;
 }
}

void SListDestroy(SList* s) {            //销毁链表
 assert(s);
 if (s->_pHead == NULL) {
  free(s->_pHead);
  return;
 }
 while (s->_pHead) {    
  PNode Tmp = s->_pHead->_PNext;
  free(s->_pHead);
  s->_pHead = Tmp;
 }
}

void SListPrint(SList* s) {             //打印链表
 assert(s);
 PNode pCur = s->_pHead;
 while (pCur) {
  printf("{%d,[%d,%s,%ld]}--->", pCur->_data,pCur->_devinfo.id,pCur->_devinfo.sn,pCur->_devinfo.timestamp);
  pCur = pCur->_PNext;
 }
 printf("\n");
}





DevList.h

 #ifndef DEV_LIST_H
#define DEV_LIST_H
#pragma once
typedef int SDataType;
typedef struct{  int id;  char sn[16];  long long timestamp;
}DevInfo;
//链表的节点
typedef struct SListNode
{
 SDataType _data;
 DevInfo _devinfo;
 struct SListNode* _PNext;
}Node,*PNode;

typedef struct SList       //封装了链表的结构
{
 PNode _pHead;//指向链表第一个节点
}SList;

void SListInit(SList*s);//链表的初始化

//在链表s最后一个节点后插入一个值为data的节点
void SListPushBack(SList* s, SDataType data ,DevInfo _devinfo );

//删除链表s最后一个节点
void SListPopBack(SList* s);

//在链表s第一个节点前插入值为data的节点
void SListPushFront(SList* s, SDataType data ,DevInfo _devinfo);

//删除链表s的第一个节点
void SListPopFront(SList* s);

//在链表的pos位置后插入值为data的节点
void SListInsert(PNode pos, SDataType data ,DevInfo _devinfo);

//删除链表s中pos位置的节点
void SListErase(SList* s, PNode pos);

// 在链表中查找值为data的节点,找到返回该节点的地址,否则返回NULL 
PNode SListFind(SList* s, SDataType data);
// 在链表中查找值为”data“的节点,找到返回该节点的地址,否则返回NULL 
PNode SListFindSn(SList* s, char* data);

//移除链表中第一个值为data的元素
void SListRemove(SList*s, SDataType data);

// 获取链表中有效节点的个数 
int SListSize(SList* s);

// 检测链表是否为空 
int SListEmpty(SList* s);

// 将链表中有效节点清空 
void SListClear(SList* s);

// 销毁链表 
void SListDestroy(SList* s);
//打印链表
void SListPrint(SList* s);
#endif


osp.c








#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>

/*pthread*/
#include "sys/ipc.h"
#include "sys/msg.h"
#include "pthread.h"
#include <arpa/inet.h>
#include <net/if.h>


#include <time.h> 
#include <sys/time.h> 


/*ListTable*/
#include  "DevList.h"


#define _T3MINUTES (3*1000000*60)
SList DevSList;
unsigned long getmillis()
{
    struct timeval tv;
    gettimeofday(&tv, 0);
    unsigned long count = tv.tv_sec * 1000000 + tv.tv_usec;
    return count / 1000;
}
void offlineManage_handle(int *arg)
{
	unsigned long lastSubMillis = 0;

	while (1)
		{
			unsigned long loopTime = getmillis();
   			if(loopTime - lastSubMillis > (1000*10))//10s 判断一次
   				{
   				
				  if(0 == SListEmpty(&DevSList) )//不为空
				  	{
				  	   
						PNode p_mov= DevSList._pHead;
					    while(p_mov!=NULL)//条件为当前节点,遍历时主要显示当前节点
					    {
					      //  printf("%d %d %s\n",p_mov->_data  ,p_mov->score,p_mov->name);
					      //获取时间戳
					        struct timeval tv;
     						gettimeofday(&tv, NULL);
     						 long long  timestamp = tv.tv_sec * 1000000 + tv.tv_usec;
							 long long  timediff  = timestamp -p_mov->_devinfo.timestamp ;
							 printf("timediff %d %d \n",timediff,_T3MINUTES);
							 if(timediff > _T3MINUTES)
							 	{
								   SListErase(&DevSList, p_mov)	;
							 }
					         p_mov=p_mov->_PNext;
					    }
				  }else {
					printf("list is empyty \n");
				  }

				  lastSubMillis = loopTime;
			}
			usleep(2000);
		}
   

}

void *Mqtt_ClentTask(void *argv)
{
  
 SListInit(&DevSList);
// SListPushBack(&s, 1);
// SListPushBack(&s, 2);
// SListPushBack(&s, 3);
   
  PNode pCur ;

  
  int cnt =0;
	while (1)
	{
		//查看设备是否在线
	   	pCur  =SListFindSn(&DevSList, "1234567890123456") ;
		struct timeval tv;
		if (NULL != pCur)//device exisist 
			{
			   printf("device  is exist  \n");
			   gettimeofday(&tv, NULL);
			   long long  timestamp = tv.tv_sec * 1000000 + tv.tv_usec;
			   SListModifyTimestamp(&DevSList, pCur->_data, timestamp );
			   	printf("Update DevSList is:\n");
				SListPrint(&DevSList);
				
		}else //non exisit 
			{
				printf("device  is non exist,cnt:%d \n",cnt);
				gettimeofday(&tv, NULL);
				long long  timestamp = tv.tv_sec * 1000000 + tv.tv_usec;
				DevInfo devinfor_tmp;
				devinfor_tmp.id =cnt ;
				memcpy(devinfor_tmp.sn,"1234567890123456",16);
				devinfor_tmp.timestamp = timestamp;
				SListPushBack(&DevSList, cnt ,devinfor_tmp);
				 printf("DevSList is:\n");
				SListPrint(&DevSList);
				cnt ++;
		}
		sleep(3);
	}




}

/*******************************************************************************
* function name	: main
* description	: main function for control_engine
* param[in] 	: none
* param[out] 	: none
* return 		: 0-success,-1-fail
*******************************************************************************/
int  main (int argc, char ** argv)
{
	
	pthread_attr_t attr;
    pthread_t pthread_id = 0 ;
	struct sched_param param;
	/*create task thread */

	
   
	  /*create task mqtt  client queue */
	pthread_attr_init (&attr);
	pthread_attr_setschedpolicy (&attr, SCHED_RR);
	param.sched_priority = 5;
	pthread_attr_setschedparam (&attr, &param);
	pthread_create (&pthread_id, &attr, &Mqtt_ClentTask, NULL);
	pthread_attr_destroy (&attr);
 

	/*create task message queue */
	offlineManage_handle(NULL);
}


打印结果
lid@lid-desktop:~/Monitor_server_1$ ./Monitor_server
list is empyty
device  is non exist,cnt:0
DevSList is:
{0,[0,1234567890123456,1614159194390317]}--->
device  is exist
Update DevSList is:
{0,[0,1234567890123456,1614159197390901]}--->
device  is exist
Update DevSList is:
{0,[0,1234567890123456,1614159200391354]}--->
device  is exist
Update DevSList is:
{0,[0,1234567890123456,1614159203392076]}--->
timediff 999069 180000000
device  is exist
Update DevSList is:
{0,[0,1234567890123456,1614159206392534]}--->
device  is exist







MakeFile 






##### Make sure all is the first target.
all:

CXX ?= g++
CC  ?= gcc




CFLAGS  += -g -pthread -Wall 
CFLAGS  += -rdynamic -funwind-tables

CFLAGS = -O2 -I./include -I./Mqtt

CFLAGS  += -I./inc    
CFLAGS  += -I./Mqtt  
DIR_LIBMQTT = Mqtt

DIR_OBJ = obj

DIRS = 	$(DIR_LIBMQTT)
FILES = $(foreach dir, $(DIRS),$(wildcard $(dir)/*.c))	
		


CFLAGS += -D__unused="__attribute__((__unused__))"

#LDFLAGS += -L./usr/lib/gpac
LDFLAGS += -ldl

LDFLAGS +=  -L./Mqtt/lib 
#-lmosquitto
LDFLAGS +=  -ldl -lm  -lstdc++


C_SRC=

C_SRC+= osp.c
C_SRC+= DevList.c
#C_SRC+= $(FILES)

CXX_SRC=


OBJ=
DEP=
OBJECTS_DIR   = objects/

# Files

CXXFLAGS += -std=c++11 $(CFLAGS)


OBJ_CAM_SRV = osp.o
TARGETS    += Monitor_server
$(TARGETS): $(OBJ_CAM_SRV)
TARGET_OBJ += $(OBJ_CAM_SRV)

FILE_LIST := files.txt
COUNT := ./make/count.sh

OBJ=$(CXX_SRC:.cpp=.o) $(C_SRC:.c=.o)
DEP=$(OBJ:.o=.d) $(TARGET_OBJ:.o=.d)

CXXFLAGS += -std=c++11 -g 
CXXFLAGS += -lc -lm -pthread
#include ./common.mk
.PHONY: all clean distclean

all: $(TARGETS)

clean:
	rm -f $(TARGETS) $(FILE_LIST)
	find . -name "*.o" -delete
	find . -name "*.d" -delete

distclean:
	rm -f $(TARGETS) $(FILE_LIST)
	find . -name "*.o" -delete
	find . -name "*.d" -delete

-include $(DEP)

%.o: %.c 
	@[ -f $(COUNT) ] && $(COUNT) $(FILE_LIST) $^ || true
	@$(CC) -c $< -MM -MT $@ -MF $(@:.o=.d) $(CFLAGS) $(LIBQCAM_CFLAGS)
	$(CC) -c $< $(CFLAGS) -o $@ $(LIBQCAM_CFLAGS) $(INCPATH)


%.o: %.cpp 
	@$(CXX) -c $< -MM -MT $@ -MF $(@:.o=.d) $(CXXFLAGS)
	$(CXX) -c $< $(CXXFLAGS) -o $@   $(INCPATH)
	

$(TARGETS): $(OBJ)
	$(CXX) -o $@ $^ $(CXXFLAGS) $(LDFLAGS)
	@[ -f $(COUNT) -a -n "$(FILES)" ] && $(COUNT) $(FILE_LIST) $(FILES) || true
	@[ -f $(COUNT) ] && $(COUNT) $(FILE_LIST) || true


#include <stdio.h>
#include "DevList.h"
#include <assert.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
 
 
void SListInit(SList*s) {
 assert(s);
 s->_pHead = NULL;
}
PNode BuySListNode(SDataType data ,DevInfo devinfo )
{ 
    PNode p; 
	p= (PNode)malloc(sizeof(Node)); 
	if (p == NULL) {
		return NULL;
	}
	p->_data=data;
	p->_devinfo.id =data;
	memcpy(p->_devinfo.sn ,devinfo.sn,16);
	p->_devinfo.timestamp = devinfo.timestamp ;
	p->_PNext=NULL; 
	return p;
}

[dl] 链接:https://pan.baidu.com/s/1fz8L8-12h-wGje58LbTccQ 
提取码:tsaa 
复制这段内容后打开百度网盘手机App,操作更方便哦 [/dl]

sitemap