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, ¶m); 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]