当前位置:网站首页>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;
}
边栏推荐
猜你喜欢
随机推荐
树莓派通过API向企业微信推送图文
小程序学习目标
2022年7月31日 暑假第三周总结
荣耀发布开发者服务平台,智慧生态合作提速
(一)、线性表的顺序存储结构链式存储结构
OpenInfra Days China 2022|SelectDB与你共享 Apache Doris 在互联网广告业务中的实践
太一集团全资收购火币旗下社交产品火信
【图像分类】2021-DeiT
CAS:474922-26-4,DSPE-PEG-NH2,DSPE-PEG-amine,磷脂-聚乙二醇-氨基供应
【技术积累】JS事件循环,Promise,async/await的运行顺序
JS中null与undefined的异同点
SQL优化最全总结 - MySQL(2022最新版)
区间贪心(区间合并)
LeetCode Question of the Day - 1403. Minimum Subsequence in Non-Increasing Order
Digital-intelligent supply chain management system for chemical manufacturing industry: build a smart supply system and empower enterprises to improve production efficiency
Thrift IDL示例文件
WPF 修改 ItemContainerStyle 鼠标移动到未选中项效果和选中项背景
数字化金融企业的产品体系长啥样?
【日记】mysql数据库连接池
Kotlin挂起函数原理是什么