当前位置:网站首页>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;
}
边栏推荐
猜你喜欢
随机推荐
【技术笔记】树莓派4B开机流程整理(无显示器安装)
dotnet remoting 抛出异常
yarn detailed introductory tutorial
图扑软件与华为云共同构建新型智慧工厂
《中国综合算力指数》《中国算力白皮书》《中国存力白皮书》《中国运力白皮书》在首届算力大会上重磅发出
怎么招聘程序员
软件测试高频面试题真实分享/网上银行转账是怎么测的,设计一下测试用例。
【MySQL】数据库的4中隔离级别
Boost library study notes (1) Installation and configuration
【日记】UPNP功能会允许自动给光猫追加端口映射
SRM Supplier Collaborative Management System Function Introduction
提高图片清晰度的快速方法?
华为云计算HCIE之oceanstor仿真器的使用操作
【LeetCode每日一题】——540.有序数组中的单一元素
如何让 JS 代码不可断点
树莓派温度监视关机保护脚本
公司自用的国产API管理神器
What does the product system of a digital financial enterprise look like?
关于ETL的两种架构(ETL架构和ELT架构)
88. (the home of cesium) cesium polymerization figure







