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]


