c语言实现 c++ list 非常方便于嵌入式stm32,具备foreach遍历功能,制定删除

一个头文件引入就可以,具备c++ foreach 遍历

list.h 头文件

#ifndef _LIST_H_
#define _LIST_H_
//编写链表 
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>

typedef void* (*_MallocType)(size_t);
typedef void (*_FreeType)(void*);


typedef struct _LIST_t
{
    void* _body;
    int   (*push_front)(struct _LIST_t* list, void* data, int len);
    int   (*push_back)(struct _LIST_t* list, void* data, int len);
    void* (*front)(struct _LIST_t* list);
    void* (*back)(struct _LIST_t* list);
    void  (*pop_front)(struct _LIST_t* list);
    void  (*pop_back)(struct _LIST_t* list);
    void  (*erase)(struct _LIST_t* list, void* data); // O(n)
    bool  (*empty)(struct _LIST_t* list);
    int   (*size)(struct _LIST_t* list);
    void  (*clear)(struct _LIST_t* list);
    void  (*foreach)(struct _LIST_t* list, void (*out_fn)(void* data));
    void  (*erase_cmp)(struct _LIST_t* list,void *del_data, bool (*cmp_fn)(void*, void*));
    void  (*destruct)(struct _LIST_t** list);
    void* (*foreach2)(struct _LIST_t* list, void* next);
}LIST_t;


static _MallocType list_malloc;
static _FreeType list_free;
/*
* @param max_num : 队列最大深度
* @param max_len : 队列最大宽度
* @param data_free : 用户自定义释放内存函数
*/
extern LIST_t* create_list(int max_num, int max_len, _MallocType fn_Malloc,_FreeType fn_Free,void (*data_free)(void*));







typedef struct _LINE_
{
    struct _LINE_* next;
    struct _LINE_* pre;
    void* data;
    uint32_t datalen;
}LINE_t;

typedef struct _BODY_
{
    LINE_t* _head;
    LINE_t* _tail;
    int _num;
    int _max_num;
    int _max_len;
    void (*_data_free)(void*);
}BODY_t;

static void _free_line_data(BODY_t* body, void* data)
{
    if(NULL == data)
        return;
    
    if(NULL != body->_data_free)
    {
            body->_data_free(data);
            return;
    }
    
    list_free(data);
}

static void _destruct(LIST_t** _list)
{
    if(NULL == _list) return;

    LIST_t* list = *_list;
    BODY_t* body = (BODY_t*)list->_body;
    list->clear(list);
    LINE_t* line = body->_head;
    if(NULL != list->_body)
    {
        list_free(list->_body);
        list->_body = NULL;
    }

    list_free(list);
    list = NULL;
}
/*
功能
清空 list 节点
参数
list:list指针
返回值 void
*/
static void _clear(LIST_t* list)
{
    BODY_t* body = (BODY_t*)list->_body;
    LINE_t* line = body->_head;
    while(line != NULL)
    {
        LINE_t* p = line->next;
        _free_line_data(body, line->data);
        list_free(line);
        line = p;
        body->_num--;
    }
    body->_head = NULL;
    body->_tail = NULL;
}
/*
功能
插入数据到 list 尾部
参数
list:list指针,data:插入数据指针,len:插入数据
返回值 int
0:成功, -1 : 超过链表最大长度或者数据长度过长,-2:内存申请失败
*/
static int _push_back(LIST_t* list, void* data, int len)
{   
    BODY_t* body = (BODY_t*) list->_body;
    if(body->_num >= body->_max_num || len > body->_max_len)
        return -1;

    LINE_t* line = (LINE_t*) list_malloc(sizeof(LINE_t));
    if(NULL == line)
        return -2;

    memset(line, 0, sizeof(LINE_t));

    line->data = list_malloc(len);
    if(NULL == line->data)
    {
        list_free(line);
        return -2;
    }
    memset(line->data, 0, len);
    memcpy(line->data, data, len);
    line->datalen = len;

    body->_num ++;

    if(NULL == body->_head) // 这里认为初始化, 头尾都指向同个结构
    {
        body->_head = line;
        body->_tail = line;
        return 0;
    }

    line->pre = body->_tail;
    body->_tail->next = line;
    body->_tail = line;

    return 0;
}
/*
功能
插入数据到 list 头部
参数
list:list指针,data:插入数据指针,len:插入数据
返回值 int
0:成功, -1 : 超过链表最大长度或者数据长度过长,-2:内存申请失败
*/
static int _push_front(LIST_t* list, void* data, int len)
{   
    BODY_t* body = (BODY_t*) list->_body;
    if(body->_num + 1 >= body->_max_num || len > body->_max_len)
        return -1;

    LINE_t* line = (LINE_t*) list_malloc(sizeof(LINE_t));
    if(NULL == line)
        return -2;

    memset(line, 0, sizeof(LINE_t));

    line->data = list_malloc(len);
    if(NULL == line->data)
    {
        list_free(line);
        return -2;
    }
    memset(line->data, 0, len);
    memcpy(line->data, data, len);
    line->datalen = len;

    body->_num ++;

    if(NULL == body->_head) // 这里认为初始化, 头尾都指向同个结构
    {
        body->_head = line;
        body->_tail = line;
        return 0;
    }

    line->next = body->_head;
    body->_head->pre = line;
    body->_head = line;

    return 0;
}
/*
功能
获取 list 头部数据
参数
list:list指针
返回值 void*
NULL:失败或者list头为空, 其他 : list头部数据
*/
static void* _front(LIST_t* list)
{
    BODY_t* body = (BODY_t*)list->_body;
    if(NULL == body)
        return NULL;
    
    return body->_head->data;
}
/*
功能
获取 list 尾部数据
参数
list:list 指针
返回值 void*
NULL:失败或者list尾为空, 其他 : list尾部数据
*/
static void* _back(LIST_t* list)
{
    BODY_t* body = (BODY_t*)list->_body;
    if(NULL == body)
        return NULL;

    return body->_tail->data;    
}

// 轮询删除, 正常不建议使用 O(n), data 是链表中的指针
static void _erase(LIST_t* list, void* data)
{
    BODY_t* body = (BODY_t*)list->_body;
    LINE_t* line = body->_head;
    while(line)
    {
        if(line->data == data)
        {
            LINE_t* p = line;
            if(NULL != p->pre)
                p->pre->next = p->next;
        
            if(NULL != p->next)
                p->next->pre = p->pre;
            
            if(body->_head == p)
            {
                body->_head = p->next;
            }
            if(body->_tail == p)
            {
                body->_tail = p->pre;
            }
            body->_num--;

            _free_line_data(body, line->data);
            list_free(line);
            break;
        }
        line = line->next;
    }
}

//删除由外部比较返回true的节点,删除后立即结束遍历
static void _erase_cmp(LIST_t* list, void* del_data, bool (*cmp_fn)(void*, void*))
{
	BODY_t* body = (BODY_t*)list->_body;
	LINE_t* line = body->_head;
	while (line)
	{
		if (cmp_fn(line->data,del_data))
		{
			LINE_t* p = line;
			if (NULL != p->pre)
				p->pre->next = p->next;

			if (NULL != p->next)
				p->next->pre = p->pre;

			if (body->_head == p)
			{
				body->_head = p->next;
			}
			if (body->_tail == p)
			{
				body->_tail = p->pre;
			}
			body->_num--;

			_free_line_data(body, line->data);
			list_free(line);
			break;
		}
		line = line->next;
	}
}
//正向遍历
static void _foreach(LIST_t* list, void (*out_fn)(void* data))
{
	BODY_t* body = (BODY_t*)list->_body;
	LINE_t* line = body->_head;
	while (line)
	{
        out_fn(line->data);
		line = line->next;
	}
}
//返回指针式的遍历
static void* _foreach2(LIST_t* list, void* next)
{
	BODY_t* body = NULL;
	LINE_t* line = NULL;
	if (next==NULL)
	{
		body = (BODY_t*)list->_body;
		line = body->_head;
	}
	else
	{
		line = (LINE_t*)next;
	}
	if (line)
	{

		line = line->next;
	}
	return (void*)line;
}
/*
功能
删除 list 头部节点
参数
list:list指针
返回值 void
*/
static void _pop_front(LIST_t* list)
{
    BODY_t* body = (BODY_t*)list->_body;
    LINE_t* line = body->_head;
    if(NULL == line)
        return;

    body->_head = line->next;

    if(NULL != body->_head)
        body->_head->pre = NULL;

    if(line == body->_tail)
        body->_tail = NULL;
    
    _free_line_data(body, line->data);
    list_free(line);

    body->_num--;
}
/*
功能
删除 list 尾部节点
参数
list:list指针
返回值 void
*/
static void _pop_back(LIST_t* list)
{
    BODY_t* body = (BODY_t*)list->_body;
    LINE_t* line = body->_tail;
    if(NULL == line)
        return;
    
    body->_tail = line->pre;

    if(NULL != body->_tail)
        body->_tail->next = NULL;

    if(line == body->_head)
        body->_head = NULL;

    _free_line_data(body, line->data);
    list_free(line);

    body->_num--;
}
/*
* 功能
list 是否为空
参数
list:list指针
返回值 bool
true:list为空,false:list不为空
*/
static bool _empty(LIST_t* list)
{
    BODY_t* body = (BODY_t*)list->_body;
    return (body->_tail == NULL);
}
/*
* 功能
获取 list 节点数量
参数
list:list指针
返回值 int
list 节点数量
*/
static int _size(LIST_t* list)
{
    BODY_t* body = (BODY_t*)list->_body;
    return body->_num;
}

static int _construct(LIST_t* list, int max_num, int max_len,void (*data_free)(void*)) // 调用前要确定 list 已经分配内存
{
	
    list->_body = list_malloc(sizeof(BODY_t));
    if(NULL == list->_body)
        return -1;
    memset(list->_body, 0, sizeof(BODY_t));
    BODY_t* body = (BODY_t*)list->_body;
    body->_max_num = max_num;
    body->_max_len = max_len;
    body->_data_free = data_free;
    
    list->push_back = _push_back;
    list->push_front = _push_front;
    list->front = _front;
    list->back = _back;
    list->pop_front = _pop_front;
    list->pop_back = _pop_back;
    list->erase = _erase;
    list->empty = _empty;
    list->size = _size;
    list->clear = _clear;
    list->destruct = _destruct;
    list->foreach = _foreach;
    list->erase_cmp = _erase_cmp;
    list->foreach2 = _foreach2;

    return 0;
}

LIST_t* create_list(int max_num, int max_len, _MallocType fn_Malloc,_FreeType fn_Free,void (*data_free)(void*))
{
	list_malloc = fn_Malloc;
	list_free = fn_Free;
    LIST_t* list =  (LIST_t*)list_malloc(sizeof(LIST_t));
    if(NULL == list)
        return NULL;
    memset(list, 0, sizeof(LIST_t));
    if( _construct(list, max_num, max_len, data_free)!= 0)
    {
        list_free(list);
        return NULL;
    }

    return list;
}



#endif


调用测试


#include "windows.h"
#include <iostream>
#include <stdio.h>
#include "list.h"

typedef struct _DATA_
{
	int len;
	char buff[];
} DATA_t;

void free_data(void* _data)
{
	DATA_t* data = (DATA_t*)_data;
	if (NULL == data)
		return;
	free(data);
}
void for_eacth_list(void *data) {
	DATA_t* it = (DATA_t*)data;
	if (NULL == it)
	{
		printf("Get front error\n");
		exit(-1);
	}
	printf("len:%d, buff:%.*s\n", it->len, it->len, it->buff);


}
bool dele_list(void* out_data, void* del_data) {
	DATA_t* it = (DATA_t*)out_data;
	DATA_t* del_datait = (DATA_t*)del_data;
	if (NULL == it|| del_data==NULL)
	{
		printf("Get front error\n");
		return false;
	}
	//printf("len:%d, buff:%.*s\n", it->len, it->len, it->buff);
	if (strcmp(it->buff, del_datait->buff)==0)
	{
		return true;
	}
	else
	{
		return false;
	}


}
void test_list(void) {
	int ccc = 10;
	for (int j=0;j<ccc;j++)
	{
		LIST_t* list = create_list(ccc, 100, malloc, free, free_data);
		if (NULL == list)
		{
			printf("Create list error\n");
			exit(-1);
		}
		for (int i = 0; i < ccc; i++)
		{
			char* num_str = (char*)malloc(99);
			sprintf(num_str, "%d", i);
			if (num_str == NULL)
			{
				printf("Create num error\n");
				exit(-1);
			}

			DATA_t* data = (DATA_t*)malloc(sizeof(DATA_t) + strlen(num_str) * sizeof(char) + 1);
			if (NULL == data)
			{
				printf("Create data error\n");
				exit(-1);
			}
			memset(data, 0, sizeof(DATA_t) + strlen(num_str) * sizeof(char) + 1);
			data->len = strlen(num_str);
			strcpy(data->buff, num_str);
			int err = list->push_back(list, data, sizeof(DATA_t) + data->len * sizeof(char) + 1);
			if (err < 0)
				printf("push back error, errcode:%d", err);

			free(num_str);
			free(data);
		}

		printf("list size:%d\n", list->size(list));
		
		list->foreach(list, for_eacth_list);
		//删除999字符串
		DATA_t* data = (DATA_t*)malloc(sizeof(DATA_t) + 100 * sizeof(char) + 1);
		if (NULL == data)
		{
			printf("Create data error\n");
			exit(-1);
		}
		memset(data, 0, sizeof(DATA_t) + 100* sizeof(char) + 1);
		data->len = 100;
		strcpy(data->buff, "9");
		list->erase_cmp(list,data, dele_list);
		/*LINE_t* itr = NULL;
		itr = (LINE_t*)list->foreach2(list, itr);
		while (itr)
		{
			DATA_t* it = (DATA_t*)itr->data;
			printf("len:%d, buff:%.*s\n", it->len, it->len, it->buff);
			itr = (LINE_t*)list->foreach2(list, itr);
		}*/
		for (LINE_t* itr = (LINE_t*)list->foreach2(list, NULL);itr; itr = (LINE_t*)list->foreach2(list, itr))
		{
			DATA_t* it = (DATA_t*)itr->data;
			printf("len:%d, buff:%.*s\n", it->len, it->len, it->buff);
		}
		//list->clear(list);
		printf("clear list size:%d\n", list->size(list));
		while (!list->empty(list))
		{
			DATA_t* it = (DATA_t*)list->front(list);
			if (NULL == it)
			{
				printf("Get front error\n");
				exit(-1);
			}
			printf("len:%d, buff:%.*s\n", it->len, it->len, it->buff);

			list->pop_front(list);
		}
		printf("list size:%d\n", list->size(list));
		list->clear(list);
		printf("list size:%d\n", list->size(list));
		list->destruct(&list);
	}
	

}

int main()
{
	test_list();

	int c = getchar();

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用foreach循环遍list集合并删除元素的方法如下: ```java List<String> list = new ArrayList<>(); list.add("stu1"); list.add("stu2"); list.add("stu3"); list.add("stu4"); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String item = iterator.next(); if (item.equals("stu2")) { iterator.remove(); } } System.out.println(list); ``` 在这个例子中,我们首先创建了一个ArrayList集合,并向其中添加了一些元素。然后,我们使用Iterator迭代器来遍集合中的元素。在遍过程中,我们使用if语句来判断当前元素是否需要删除,如果需要删除,则使用Iterator的remove()方法来删除该元素。最后,我们打印出删除元素后的集合内容。 请注意,使用foreach循环遍集合时,不能直接在循环中删除元素,因为这会导致ConcurrentModificationException异常。因此,我们需要使用Iterator来进行安全的删除操作。 #### 引用[.reference_title] - *1* [foreach集合](https://blog.csdn.net/m0_53821599/article/details/119655736)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [mybatis使用foreachlist集合或者array数组方](https://blog.csdn.net/weixin_43982687/article/details/126475109)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值