日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

第六天2017/04/11(2:Linux内核链表Demo、顺序表、链表的开发与设计)

發布時間:2025/3/21 linux 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第六天2017/04/11(2:Linux内核链表Demo、顺序表、链表的开发与设计) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
//結構體相關的高級話題#include "stdio.h" #include "stdlib.h" #include "string.h" //定義一個結構體,就相當于各個變量的偏移量也定下來了 struct student {char name[32]; //32個字節int age; //4個字節char *na; //4個字節 };int main() {struct student s = {"Mr.right" , 24 , "Victory"};struct student *p = &s;p = p+1;p = 0; //p = p - p; //此時 p 相當于 ((struct student *)0)int i = (int )(&(p->name)); //0 int i = (int)(&(((struct student *)0)->name))int j = (int )(&(p->age)); //32 int j = (int)(&(((struct student *)0)->age))int k = (int )(&(p->na)); //36 int k = (int)(&(((struct student *)0)->na))int m = (int)&(((struct student *)0)->name);//把0地址空間進行類型轉換,轉換為struct student *的結構體指針;此處 //再指向結構體中的age; 此處->是一個尋址操作,就是計算age的地址在哪里,沒有往age所指向的內存空間讀寫數據//尋址操作對CPU來講,只不過是一個+-*/操作 //再取地址 ; //在把地址轉換成十進制 } ==================================================================================//【疑問】為什么講上面的知識:(int)&(((struct student *)0)->age)? //【答】是為了引出“Linux內核鏈表了解”!Linux內核鏈表了解: //不是鏈表包含業務結點 //而是業務結點包含鏈表//如何從鏈表結點的位置找到業務結點的位置呢?#define offsetof(TYPE,MEMBER) ((size_t)&((TYPE*)0)->MEMBER) //求出MEMBER相對于TYPE結構體的偏移量offset#define container_of(ptr,type,member) (type*)((char*)ptr - offsetof(type,member)) //求整個結構體的偏移量

下圖是Linux內核鏈表的示意圖:可以通過鏈表結點,根據偏移量offset找到
業務結點的起始地址,對業務結點進行操作。

============================================================================

上述圖簡單介紹了公司的業務數據的設計,代碼如下:
實現:讓業務結點和鏈表結點進行有效的分離

#include<iostream> using namespace std;struct List //鏈表結點 {struct List *next; };struct student //業務結點(中有鏈表結點) {//數據元素int age;char name[100];//鏈表結點struct List node; };void insert_node(struct List *pNew,struct List *pHead) //插入鏈表結點 //注解:不用插入業務結點,實質上只要插入鏈表結點就可以(因為可以通過鏈表結點找到業務結點,并對業務結點進行訪問) {pNew->next = pHead->next; //此時用的是頭插法,打印時,輸出結果是逆序的pHead->next = pNew; }void printf_age(struct List *pHead) //打印業務結點 //就像上面說的那樣,遍歷鏈表結點,通過鏈表結點找到業務結點的入口,并對業務結點的數據元素進行訪問 {//計算偏移量int offset = (int)&(((struct student*)0)->node);//找到每一個結點的指針struct List *pCur = pHead->next;while(pCur){struct student* pCur_stu = (struct student*)((char*)pCur - offset);cout<<pCur_stu->age<<endl;pCur = pCur->next;} } int main() {struct List pHead; //定義一個鏈表頭結點pHead.next = NULL;struct student a,b,c,d;a.age = 20;b.age = 21;c.age = 22;d.age = 23;insert_node(&a.node,&pHead); //把鏈表結點插入到鏈表結點的頭結點上insert_node(&b.node,&pHead);insert_node(&c.node,&pHead);insert_node(&d.node,&pHead);printf_age(&pHead); //打印鏈表結點return 0; }

實質上可以進行“投機取巧,即永遠把鏈表結點放在業務結點的第一個位置,此時:鏈表結點相對于業務結點的偏移量offset為0.

struct List //鏈表結點 {struct List *next; };struct student //業務結點(中有鏈表結點) {//鏈表結點struct List node;//數據元素int age;char name[100]; }; 1、企業級財富庫線性表之單鏈表開發和設計】 //linklist.h函數聲明 #ifndef _MYLINKLIST_H_ #define _MYLINKLIST_H_typedef void LinkList;typedef struct _tag_LinkListNode {struct _tag_LinkListNode* next; }LinkListNode;LinkList* LinkList_Create(); void LinkList_Destroy(LinkList* list); void LinkList_Clear(LinkList* list); int LinkList_Length(LinkList* list); int LinkList_Insert(LinkList* list, LinkListNode* node, int pos); LinkListNode* LinkList_Get(LinkList* list, int pos); LinkListNode* LinkList_Delete(LinkList* list, int pos); #endif ========================================================================= //linklist.cpp函數實現 #include "stdlib.h" #include "stdio.h" #include "string.h"#include "linklist.h"typedef struct _tag_LinkList {LinkListNode header;int length; }TLinkList;LinkList* LinkList_Create() {TLinkList *tList = (TLinkList *)malloc(sizeof(TLinkList));if (tList == NULL){return NULL;}tList->header.next = NULL;tList->length = 0;return tList; }void LinkList_Destroy(LinkList* list) {if (list != NULL){free(list);}return ; }void LinkList_Clear(LinkList* list) {TLinkList *tList = (TLinkList *)list;if (tList == NULL){return ;}tList->length = 0;tList->header.next = NULL;return ; }int LinkList_Length(LinkList* list) {TLinkList *tList = (TLinkList *)list;if (tList == NULL){return -1;}return tList->length; }int LinkList_Insert(LinkList* list, LinkListNode* pNew, int pos) {//將業務結點s中的s.node元素插入到單鏈表中int i = 0;TLinkList *tList = (TLinkList *)list;LinkListNode *current = NULL;if (tList == NULL || pNew == NULL || pos<0){return -1;}current = &tList->header; //環境初始化for (i=0; (i<pos)&&current->next!=NULL; i++ ) //尋找插入位置{current = current->next;} //插入新結點pNewpNew->next = current->next;current->next = pNew;tList->length ++;return 0; }LinkListNode* LinkList_Get(LinkList* list, int pos) {int i = 0;TLinkList *tList = (TLinkList *)list;LinkListNode *current = NULL;LinkListNode *ret = NULL;if (list==NULL || pos<0 || pos>=tList->length){return NULL;}current = &tList->header;for (i=0; i<pos; i++){current = current->next;}ret = current->next;return ret; }LinkListNode* LinkList_Delete(LinkList* list, int pos) {int i = 0;TLinkList *tList = (TLinkList *)list;LinkListNode *current = NULL;LinkListNode *ret = NULL;if (list==NULL || pos<0 || pos>=tList->length){return NULL;}//沒有初始化環境current = &tList->header;for (i=0; i<pos; i++){current = current->next;}ret = current->next;current->next = ret->next;tList->length --;return ret; } ========================================================================= //main.cpp測試程序 #include "linklist.h" #include <iostream> using namespace std;struct Student {LinkListNode node; //Linux內核原理:業務結點中有鏈表結點char name[100];int age; };void print_LinkList(void* list) //遍歷打印鏈表 {for (int i=0; i<LinkList_Length(list); i++){struct Student *tmp = (struct Student*)LinkList_Get(list, i);printf("name: %s , age: %d\n", tmp->name,tmp->age);} }int main() {Student s1; strcpy(s1.name,"Tom"); s1.age = 20;Student s2; strcpy(s2.name,"Tim"); s2.age = 21;Student s3; strcpy(s3.name,"Kim"); s3.age = 22;LinkList* list = list = LinkList_Create(); /************************************************************************/ //case1:LinkList_Insert(list,&s1.node,0); //把s1中的鏈表結點s1.node結點插入到鏈表listLinkList_Insert(list,&s2.node,0); //把s2中的鏈表結點s2.node結點插入到鏈表listLinkList_Insert(list,&s3.node,0); //把s3中的鏈表結點s3.node結點插入到鏈表list//LinkList_Insert(list,(LinkListNode*)(&s1.node),0);//LinkList_Insert(list,(LinkListNode*)(&s2.node),0);//LinkList_Insert(list,(LinkListNode*)(&s3.node),0); //case2://LinkList_Insert(list,(LinkListNode*)(&s1),0);//LinkList_Insert(list,(LinkListNode*)(&s2),0);//LinkList_Insert(list,(LinkListNode*)(&s3),0);print_LinkList(list); /************************************************************************/cout<<"刪除結點"<<endl;LinkList_Delete(list,1);print_LinkList(list);} /************************************************************************/ /************************************************************************/2、企業級財富庫線性表之順序存儲開發和設計】 【核心問題】業務數據 和 鏈表算法(底層庫)是如何分離的? //seqlist.h:函數聲明 #ifndef __MY_SEQLIST_H__ #define __MY_SEQLIST_H__typedef void SeqList; typedef void SeqListNode;//疑問:為什么傳入的形參類型、返回的類型為void* ? //答:底層不想讓別人知道我是什么結構的,也沒有必要讓別人知道SeqList* SeqList_Create(int capacity); //創建容量為capacity的順序線性表 void SeqList_Destroy(SeqList* list); //釋放線性表list void SeqList_Clear(SeqList* list); //清空線性表list int SeqList_Length(SeqList* list); int SeqList_Capacity(SeqList* list); int SeqList_Insert(SeqList* list, SeqListNode* node, int pos); SeqListNode* SeqList_Get(SeqList* list, int pos); SeqListNode* SeqList_Delete(SeqList* list, int pos); int for_each(void (*CALLBACK_print)(void*),void* list); //回調函數循環遍歷 #endif //void* SeqList_Create(int capacity); //void SeqList_Destroy(void* list); //void SeqList_Clear(void* list); //int SeqList_Length(void* list); //int SeqList_Capacity(void* list); //int SeqList_Insert(void* list, void* node, int pos); //void* SeqList_Get(void* list, int pos); //void* SeqList_Delete(void* list, int pos);=============================================================================== //seqlist.cpp:函數實現 #include "seqlist.h" #include "stdlib.h" #include "stdio.h" #include "string.h"typedef struct _tag_SeqList {int capacity; //sizeof(數組),數組實際占有的內存大小int length; //strlen(數組),數組中存放著幾個數據unsigned int *node ; //數組的頭指針 }TSeqList;//typdef的意思 把void 重新命名成SeqList/* void * SeqList_Create2(int capacity) //分配兩次內存,惡心! {TSeqList *ret = NULL;ret = (TSeqList *)malloc(sizeof(TSeqList));if (ret == NULL){return NULL;}ret->capacity = capacity;ret->node = (unsigned int *)malloc(sizeof(unsigned int ) * capacity);if (ret->node == NULL){return NULL;}ret->length = 0;return ret; } */void * SeqList_Create(int capacity) //創建一個長度為capacity的數組,數組的數據類型是unsigned int {TSeqList *ret = NULL;if (capacity <= 0){return NULL;}ret = (TSeqList *)malloc(sizeof(TSeqList) + sizeof(unsigned int ) * capacity );//一次性全部分配內存if (ret == NULL){return NULL;}ret->capacity = capacity; ret->length = 0;ret->node = (unsigned int *)(ret + 1);return ret; }void SeqList_Destroy(SeqList* list) {if (list == NULL){return ;}free(list);return ; }void SeqList_Clear(SeqList* list) //不是釋放內存,是直接把長度設為0 {TSeqList *tlist = NULL;if (list == NULL){return ;}tlist = (TSeqList *)list;tlist->length = 0;//直接把長度設為0return ; }int SeqList_Length(SeqList* list) {TSeqList *tlist = (TSeqList *)list;if (list == NULL){return -1;}return tlist->length; }int SeqList_Capacity(SeqList* list) {TSeqList *tlist = (TSeqList *)list;if (list == NULL){return -1;}return tlist->capacity; } //注解:實際位置和下標位置總是相差1 int SeqList_Insert(SeqList* list, SeqListNode* node, int pos) //插入位置:length+1>=pos>=1 {if(list == NULL||node == NULL)return -1;TSeqList *tlist = (TSeqList*)list; //capacity空間不夠if(tlist->length >= tlist->capacity) return -2; //容錯 //插入位置length+1>=pos>=1if(pos > tlist->length+1){pos = tlist->length;}if(pos < 1){pos = 1;} //插入操作int i = tlist->length-1; //最后一個有效元素的位置while(i>=pos-1) //循環后移{tlist->node[i+1] = tlist->node[i];i--;}tlist->node[pos-1] = (unsigned int)node; //插入tlist->length++;return 0; }SeqListNode* SeqList_Get(SeqList* list, int pos) //查找位置:length>=pos>=1 {TSeqList *tlist = (TSeqList *)list;if (list== NULL || pos<1 || pos>tlist->length){return NULL;}return (SeqListNode*)tlist->node[pos-1]; }SeqListNode* SeqList_Delete(SeqList* list, int pos) //刪除位置:length>=pos>=1 {int i = 0;TSeqList *tlist = (TSeqList *)list;SeqListNode* ret = NULL;if (list == NULL || pos<1 || pos>tlist->length){return NULL;} //緩存要刪除的結點ret = (SeqListNode*)tlist->node[pos-1]; //對鏈表元素值循環前移i = pos-1;while(i<=tlist->length-1){tlist->node[i] = tlist->node[i+1];i++;} //刪除后,長度-1tlist->length --;return ret; }int for_each(void (*CALLBACK_print)(void*),void* list) {if(list == NULL)return -1;(*CALLBACK_print)(list);return 0; } =============================================================================== //線性表順序存儲測試.cpp:測試代碼 #include "seqlist.h" #include "stdlib.h" #include "stdio.h" #include "string.h"typedef struct _Teacher //業務結點 {char name[64];int age ; }Teacher;void CALLBACK_print(void* list) //循環遍歷的回調函數 {printf("循環遍歷:\n");for (int i=1; i<=SeqList_Length(list); i++){Teacher *tmp = (Teacher *)SeqList_Get(list, i);printf("name:%s , age:%d \n", tmp->name,tmp->age);} }void main() { //創建業務數據,并初始化Teacher t1 = {"Kobe",20};Teacher t2 = {"James",19};Teacher t3 = {"Curry",16}; //環境準備int ret = 0, i = 0;SeqList* list = NULL; //創建線性表list = SeqList_Create(10);//仔細思考:業務數據 和 鏈表算法(底層庫)是如何分離的。。。。。。//業務數據結點的管理(內存的生命周期)甩給了上層應用(業務模型) //插入ret = SeqList_Insert(list, (SeqListNode*)&t1, 1);ret = SeqList_Insert(list, (SeqListNode*)&t2, 1);ret = SeqList_Insert(list, (SeqListNode*)&t3, 1); //循環遍歷for_each(CALLBACK_print,list); //刪除 SeqList_Delete(list, 2);for_each(CALLBACK_print,list); //銷毀線性表SeqList_Destroy(list);system("pause"); }

總結

以上是生活随笔為你收集整理的第六天2017/04/11(2:Linux内核链表Demo、顺序表、链表的开发与设计)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 午夜宫 | 超能一家人电影免费喜剧在线观看 | 日韩激情一区二区三区 | 午夜毛片 | 激情六月| 新x8x8拨牐拨牐永久免费影库 | 日本少妇xxx | 日本一区二区人妻 | 国偷自产av一区二区三区麻豆 | 在线观看亚洲国产 | 国产精品12p| 国产精品美女av | 欧美少妇xx | 99re在线视频 | 日韩成人久久 | 亚洲精品视频在线观看视频 | 一区二区三区啪啪啪 | 成年人在线视频 | 黄色大片免费网站 | 日本一级吃奶淫片免费 | 亚洲精品视频在线观看视频 | 久久久久亚洲av成人片 | av在线www | sese欧美 | 久久6精品| 拔擦8x成人一区二区三区 | 91人人干| 丁香花电影高清在线阅读免费 | 亚洲制服丝袜在线播放 | 99热这里有| 星空大象mv高清在线观看免费 | 亚洲一级Av无码毛片久久精品 | av影库| 日本一区二区三区视频在线 | 欧美乱日| 日本人极品人妖高潮 | 狼人综合视频 | 一区二区三区在线看 | 国产永久免费视频 | 国产精品久久久久久久一区二区 | 久热中文字幕 | 一个人在线观看www软件 | 国产三级精品三级在线 | 精品人妻一区二区三区久久 | 色呦呦入口 | 在线观看国产精品入口男同 | 插我一区二区在线观看 | 97国产视频 | 少妇熟女一区 | 伊人久久免费视频 | 2021av在线 | 91青青草视频 | 亚洲午夜不卡 | 91麻豆国产视频 | 黄色小说视频网站 | 欧美一级黄 | 日韩欧美高清 | 久久噜噜色综合一区二区 | 久久国产欧美 | 天堂网av在线播放 | 嫩草一区二区 | 免费大片在线观看www | 成年人黄色片网站 | 波多野结衣在线一区 | 成人在线免费观看网站 | 国产在线国偷精品免费看 | 久久午夜精品 | 久久国内精品视频 | 欧美日韩国产在线一区 | 91理论片 | 国产精品aⅴ | 国产尤物av | 日本黄色电影网址 | 黑人100部av解禁片 | 免费在线观看av网址 | 国产群p| 免费av在线播放网址 | 手机看片久久 | 男人天堂怡红院 | 在线观看黄色av网站 | 亚洲视频精选 | 中文字幕乱码无码人妻系列蜜桃 | 久福利 | 伊人五月天 | 日本高清不卡在线观看 | 日本美女黄色 | 欧美丝袜一区二区三区 | 秋霞国产精品 | 亚洲av综合色区无码一区爱av | 小辣椒福利视频导航 | 欧美群交射精内射颜射潮喷 | 亚洲Av无码成人精品区伊人 | 久草三级 | 黄色录象片 | 四虎精品永久在线 | 狠狠插av| 国产一区二区三区免费在线观看 | 中国一区二区三区 | 国产真实的和子乱拍在线观看 |