Linux内核链表???
难道普通的链表不满足?,当然满足了 但是感觉缺少点对链表深刻了解的过程
普通链表结点 数据域 and 指针域
Lnux内核链表结点 指针域 只有指针域 那怎么放数据呢??
通过结构体定义 链表结点元素 数据1,数据2… 数据n-1 定义多少个数据都可以 ,但是最后一个必须 为Lnux内核链表结点 变量或者指向堆内存空间 的指针
首先分析一下 为啥使用Linux内核链表
生活当中的 汽车和客车和高铁 民用客机,他们有一个共同的 特征:座椅 所谓的座椅 就是这些民用汽车和客车 高铁 民用客机就是这些 数据 也就是普通链表 货车 运煤炭的火车车箱底部是空的 就可以载人 或许有一定的危险性 开快了会直接 哦呐呐呐+ 黑人抬棺BGM …脑补一下画面,
这些最好是拿来运一些煤炭,或者放一些集装箱 之类的 这有那个装箱子
, 这些就是底盘 数据放在另一个结构体里方便数据操作
- 看看大概的样子
- 大块的矩形 — 数据
- 两个合成的矩形 — 结点
- 这要包含这个小结点 就能访问 小结点 上面对的数据
Lnux内核链表结点变量
直接上C/C++ 代码
#include<iostream>
using namespace std;
//Linux 共享 双向链表结点
using LinkNode = struct __DoubleLinkNode;
//Linux 共享 双向链表结点
struct __DoubleLinkNode {
LinkNode* prev;
LinkNode* next;
};
//Linux 共享 双向链表
struct __DoubleLinkList {
LinkNode *List;
size_t size;
};
struct Student{
char name[14];
int age;
};
struct LinkElem{
Student s;
LinkNode node;
};
using LinkList = __DoubleLinkList;
void initLinkList(LinkList& List, LinkNode * const initList=nullptr) {
List.List = new LinkNode{ initList, initList };
List.size = 0u;
}
void Link(LinkNode*& node, LinkNode*& newnode) {
if (node->next) {
node->next->prev = newnode;
newnode->next = node->next;
}
newnode->prev = node;
node->next = newnode;
}
void LinkListInsert_back(LinkList& List, LinkNode*& Newnode) {
LinkNode* current = List.List;
while (current->next) {
current = current->next;
}
Link(current, Newnode);
++List.size;
}
void LinkListDestroy(LinkList& List) {
LinkNode* &iter = List.List;
LinkNode*& iterNext = iter->next = iter->next->next = iter->next->prev = nullptr;
delete iter;
iter = iterNext=nullptr;
List.size = (size_t)iter;
}
LinkElem* CreatorLinkElem(const size_t& size) {
return new LinkElem[size];
}
void LinkElemDestroy(LinkElem*&e) {
delete[] e;
e = nullptr;
}
int main(void) {
LinkList List;
initLinkList(List);
size_t LinkElemArraySize = 26;
LinkElem* e = nullptr;
const char studentName[] = "ABCDEFGHIJKLMNOPQRTUVWXYZ\0";
e = CreatorLinkElem(LinkElemArraySize);
for (size_t i = 0; i < LinkElemArraySize; i++){
strcpy_s(e[i].s.name, {"Student_"});
strncat_s(e[i].s.name, &studentName[i], 1);
const int age = LinkElemArraySize - 3;
e[i].s.age = age % 18 + 13;
e[i].node = LinkNode{nullptr};
LinkNode*node =&e[i].node;
LinkListInsert_back(List, node);
}
LinkNode* current = List.List->next;
const size_t LinkElemNodeoffset = offsetof(LinkElem, node);
while (( current)->next){
LinkElem*&& elemvalue = (LinkElem*)((size_t)current - (size_t)LinkElemNodeoffset);
cout << " 学生姓名:" << elemvalue->s.name << "\t学生年龄:" << elemvalue->s.age << endl;
current = (current)->next;
}
LinkElemDestroy(e);
LinkListDestroy(List);
return 0;
}
源码解析:
offsetof(LinkElem, node); 求node 在这个结构体偏移量
首先说明一下: 栈和堆 只要是顺序的内存空间都可以做链接成链表 ,不是顺序无法找到偏移量 栈是可以的找到偏移量 ,堆就不可行
根据偏移量 找到的node结点 访问数据
Lnux内核链表结点指针
#include<iostream>
using namespace std;
//Linux 共享 双向链表结点
using LinkNode = struct __DoubleLinkNode;
//Linux 共享 双向链表结点
struct __DoubleLinkNode {
LinkNode* prev;
LinkNode* next;
};
//Linux 共享 双向链表
struct __DoubleLinkList {
LinkNode *List;
size_t size;
};
struct Student{
char name[32];
int age;
};
struct LinkElem{
Student s;
LinkNode *node;
};
using LinkList = __DoubleLinkList;
void initLinkList(LinkList& List, LinkNode * const initList=nullptr) {
List.List = new LinkNode{ initList, initList };
List.size = 0u;
}
void Link(LinkNode*& node, LinkNode*& newnode) {
if (node->next) {
node->next->prev = newnode;
newnode->next = node->next;
}
newnode->prev = node;
node->next = newnode;
}
void LinkListInsert_back(LinkList& List, LinkNode*& Newnode) {
LinkNode* current = List.List;
while (current->next) {
current = current->next;
}
Link(current, Newnode);
++List.size;
}
void LinkListDestroy(LinkList& List) {
LinkNode* &iter = List.List;
LinkNode* iterNext = iter->next;
delete iter;
iter = iterNext;
while (iter){
iterNext = iter->next;
iter->prev = nullptr;
iter->next = nullptr;
iter = iterNext;
}
iter = nullptr;
List.size = (size_t)iter;
}
LinkElem* CreatorLinkElem(const size_t& size) {
return new LinkElem[size];
}
void LinkElemDestroy(LinkElem*& e) {
delete[] e;
e = nullptr;
}
int main(void) {
LinkList List;
initLinkList(List);
size_t LinkElemArraySize = 26;
LinkElem* e = CreatorLinkElem(LinkElemArraySize);
const char studentName[] = "ABCDEFGHIJKLMNOPQRTUVWXYZ";
for (size_t i = 0; i < LinkElemArraySize; i++){
strcpy_s(e[i].s.name, { "Student_" });
strncat_s(e[i].s.name, &studentName[i], 1);
const int age = LinkElemArraySize;
e[i].s.age = age % 18+13;
e[i].node = new LinkNode;
cout << "node 分配的地址为 " << e[i].node << endl;
e[i].node->prev = nullptr;
e[i].node->next = nullptr;
}
for (size_t i = 0; i < LinkElemArraySize; i++) {
LinkNode*node = (e + i)->node;
LinkListInsert_back(List, node);
}
LinkNode* current = List.List->next;
size_t i = 0;
while (current-?next){
const LinkElem* eptr = e + i;
//获取node 偏移量
const size_t LinkElemNodeoffset = ((size_t)current - (size_t)eptr);
LinkElem* elemvalue = (LinkElem*)((size_t)current - LinkElemNodeoffset);
cout << " 学生姓名:" << elemvalue->s.name << "\t学生年龄:" << elemvalue->s.age << endl;
++i;
current = current->next;
}
LinkListDestroy(List);
LinkElemDestroy(e);
return 0;
}
注意事项:栈和堆 只要是顺序的内存空间都可以做链接成链表 ,不是顺序无法找到偏移量 栈是可以的找到偏移量 ,
堆就不可行