当前位置:网站首页>darknet source code reading notes-02-list.h and lish.c
darknet source code reading notes-02-list.h and lish.c
2022-08-04 17:33:00 【Mr.Q】
1. list.h
#ifndef LIST_H
#define LIST_H
// cfg文件每一个[xxx]代表一个片区(section),通常表示的是一个 层(layer)
// 链表中的每个node,都是一个section.
// 双向链表的节点定义
typedef struct node{
void *val; // Stores a pointer to the actual value.
struct node *next; // 指向当前节点的下一节点
struct node *prev; // 指向当前节点的上一节点
} node;
// Doubly linked list of network configurations,存储cfg网络配置文件.
// // 双向链表
typedef struct list{
int size; // The number of nodes in the profile,即section个数,通常就是layer层数
node *front; // 头指针,The first node of the linked list of pointers
node *back; // 尾指针,The last node of the linked list of pointers
} list;
#ifdef __cplusplus
extern "C" { // 会指示编译器这部分代码按C语言(而不是C++)的方式进行编译.
#endif
list *make_list();
int list_find(list *l, void *val);
void list_insert(list *, void *);
void **list_to_array(list *l);
void free_list_val(list *l);
void free_list(list *l);
void free_list_contents(list *l);
void free_list_contents_kvp(list *l);
#ifdef __cplusplus
}
#endif
#endif
2.lish.c
#include <stdlib.h>
#include <string.h>
#include "list.h"
#include "utils.h"
#include "option_list.h"
/// <summary>
/// 创建双向链表
/// </summary>
/// <returns>返回双向链表</returns>
list *make_list()
{
list* l = (list*)xmalloc(sizeof(list));
l->size = 0;
l->front = 0;
l->back = 0;
return l;
}
/*
void transfer_node(list *s, list *d, node *n)
{
node *prev, *next;
prev = n->prev;
next = n->next;
if(prev) prev->next = next;
if(next) next->prev = prev;
--s->size;
if(s->front == n) s->front = next;
if(s->back == n) s->back = prev;
}
*/
/// <summary>
/// 删,Doubly linked list deletes the tail node.
/// </summary>
/// <param name="l"></param>
/// <returns></returns>
void *list_pop(list *l){
if(!l->back) return 0;
node *b = l->back; //获取尾节点,指针b备份
void *val = b->val;
l->back = b->prev; // 删除尾节点
if(l->back) l->back->next = 0; // 尾节点的next指针置为空.
free(b);
--l->size; // --(l->size)
return val;
}
/// <summary>
/// 增,尾插法.
/// </summary>
/// <param name="l"></param>
/// <param name="val">Generic interface can be implemented,即可以是int *val也char *val</param>
void list_insert(list *l, void *val)
{
node* newnode = (node*)xmalloc(sizeof(node)); // First generate new nodes
newnode->val = val;
newnode->next = 0;
if(!l->back){ // 尾节点为空,则为空链表
l->front = newnode; // 此时新节点,is the first node
newnode->prev = 0; // pointing back and forth.The front pointer of the first node is null.
}else{
l->back->next = newnode; // 尾节点不为空,Use tail interpolation.
newnode->prev = l->back; // pointing back and forth.
}
l->back = newnode; // 更新尾节点指针
++l->size;
}
/// <summary>
/// Release the space of the current node and subsequent nodes
/// </summary>
/// <param name="n">节点的指针</param>
void free_node(node *n)
{
node *next;
while(n) {
next = n->next; // Back up the later nodes first
free(n); // Then release the current node space
n = next; // 遍历下一个节点.
}
}
/// <summary>
/// Release the value stored in the linked list.Inside the node is a pointer to the actual value.
/// </summary>
/// <param name="l"></param>
void free_list_val(list *l)
{
node *n = l->front; // 遍历节点,指向链表头节点.
node *next; // Temporary backup node
while (n) {
next = n->next; // Backup the next node
free(n->val); // Frees the pointer to the actual value.
n = next; // 遍历下一个节点.
}
}
/// <summary>
/// Free the entire list space
/// </summary>
/// <param name="l"></param>
void free_list(list *l)
{
free_node(l->front); // Release the space of the current node and subsequent nodes
free(l);
}
/// <summary>
/// Frees the stored value of the entire linked list
/// </summary>
/// <param name="l"></param>
void free_list_contents(list *l)
{
node *n = l->front;
while(n){
free(n->val); // What is actually freed is the pointer holding the value.
n = n->next;
}
}
/// <summary>
/// ?
/// </summary>
/// <param name="l"></param>
void free_list_contents_kvp(list *l)
{
node *n = l->front;
while (n) {
kvp* p = (kvp*)n->val; // 强转为kvp结构体指针. ?
free(p->key); // ?
free(n->val);
n = n->next;
}
}
/// <summary>
/// 链表转数组,That is, all the stored values in the linked list,用数组保存
/// </summary>
/// <param name="l"></param>
/// <returns>二维指针,Because the value stored in each node is void类型的指针,Hence the pointer of the pointer,That is, a two-dimensional pointer</returns>
void **list_to_array(list *l)
{
// 分配存储空间,长度l-size, Each space is one sizevoid类型指针.a指向的是void类型指针的指针.
void** a = (void**)xcalloc(l->size, sizeof(void*));
int count = 0;
node *n = l->front; // 遍历指针n指向头节点.
while(n){
a[count++] = n->val; //
n = n->next;
}
return a;
}
边栏推荐
- 又一款高颜值 Redis 官方可视化工具,功能真心强大!
- Clearance sword refers to Offer——The sword refers to Offer II 010. and the sub-array of k
- 微信jsApi调用失效的相关问题
- clickhouse 上下线表
- 】 【 LeetCode daily one problem - 540. The order of a single element of the array
- php如何查询字符串以什么开头
- 怎么面试程序员的?傲慢与无礼,就数他牛逼
- LeetCode 每日一题——1403. 非递增顺序的最小子序列
- 小程序经典案例
- R语言dplyr包group_by函数和summarise_at函数计算dataframe计算不同分组的计数个数和均值、使用%>%符号将多个函数串起来
猜你喜欢
随机推荐
荣耀发布开发者服务平台,智慧生态合作提速
【无标题】
微信jsApi调用失效的相关问题
信息系统项目管理师必背核心考点(六十)项目集管理
44. 通配符匹配 ●●● & HJ71 字符串通配符 ●●
C# Sqlite database construction and use skills
树莓派安装samba用来共享文件
SRM供应商协同管理系统功能介绍
【技术积累】JS事件循环,Promise,async/await的运行顺序
华为云计算HCIE之oceanstor仿真器的安装教程
小程序学习目标
Qt自动补全之QCompleter使用
小满nestjs(第一章 介绍nestjs)
启动项目(瑞吉外卖)
.NET云原生应用发展论坛--8月7日邀你一起云上探索
小程序+自定义插件的混合模式
树莓派温度监视关机保护脚本
设置表头颜色
php如何查询字符串以什么开头
语音识别学习资源