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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

二维指针操作链表

發布時間:2023/11/27 生活经验 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二维指针操作链表 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背景

Linus slashdot: ? ?https://meta.slashdot.org/story/12/10/11/0030249

Linus大嬸在slashdot上回答一些編程愛好者的提問,其中一個人問他什么樣的代碼是他所喜好的,大嬸表述了自己一些觀點之后,舉了一個指針的例子,解釋了什么才是core low-level coding

下面是Linus的教學原文及翻譯——

“At the opposite end of the spectrum, I actually wish more people understood the really core low-level kind of coding. Not big, complex stuff like the lockless name lookup, but simply good use of pointers-to-pointers etc. For example, I’ve seen too many people who delete a singly-linked list entry by keeping track of the “prev” entry, and then to delete the entry, doing something like。(在這段話的最后,我實際上希望更多的人了解什么是真正的核心底層代碼。這并不像無鎖文件名查詢(注:可能是git源碼里的設計)那樣龐大、復雜,只是僅僅像諸如使用二級指針那樣簡單的技術。例如,我見過很多人在刪除一個單項鏈表的時候,維護了一個”prev”表項指針,然后刪除當前表項,就像這樣)”

if (prev)prev->next = entry->next;elselist_head = entry->next;

and whenever I see code like that, I just go “This person doesn’t understand pointers”. And it’s sadly quite common.(當我看到這樣的代碼時,我就會想“這個人不了解指針”。令人難過的是這太常見了。

我嘗試用二維指針操作鏈表,寫了如下code。

希望領悟到二維指針的精髓。

#include <stdio.h>
#include <stdlib.h>typedef struct Node {struct Node *next;int data;
} node;void initList(node **head, unsigned int size)
{node **cur = head;for (int i=0; i<size; i++){*cur = (node *)malloc(sizeof(node));(*cur)->data = i;(*cur)->next = NULL;cur = &(*cur)->next;		}
}void deleteList(node **head, int data)
{for (node **cur=head; *cur;){node *entry = *cur;if (entry->data == data){*cur = entry->next;free(entry);entry = NULL;}elsecur = &entry->next;}
}void freeList(node **head)
{for (node **cur=head; *cur;){node *entry = *cur;*cur = entry->next;free(entry);entry = NULL;}
}int main()
{node *head = NULL;unsigned int size = 5;initList(&head, 5);if (NULL == head){printf("head is null, init list failed");return -1;}else{printf("init list suc, addr is: \n");node *cur = head;while(NULL != cur){printf("%X ", cur);cur = cur->next;}		}printf("\n\n");node *cur = head;printf("list data: \n");while(NULL != cur){printf("%d ", cur->data);cur = cur->next;}printf("\n\n");printf("delete node 3 from list\n\n");deleteList(&head, 3);cur = head;printf("list data: \n");while(NULL != cur){printf("%d ", cur->data);cur = cur->next;}printf("\n\n");printf("free list\n\n");freeList(&head);cur = head;printf("list data: \n");	while(NULL != cur){printf("%d ", cur->data);cur = cur->next;}printf("\n");return 0;
}

運行結果如下:

init list suc, addr is:?
4B8260 4B8280 4B82A0 4B82C0 4B82E0?

list data:?
0 1 2 3 4?

delete node 3 from list

list data:?
0 1 2 4?

free list

list data:?

Q1: 如果我們用下面的initList_1來代替原來的initList,重新build,運行,你想想會發生什么?

list 能初始化成功嗎?

void initList_1(node **head, unsigned int size)
{node **cur = head;for (int i=0; i<size; i++){node *entry = *cur;entry = (node *)malloc(sizeof(node));entry->data = i;entry->next = NULL;cur = &entry->next;		}
}

A:list不能初始化成功,*head 并沒有指向分配的內存,依然為NULL, entry 指向的內存并不能返回到函數外部。

Q2: 上面的freeList 函數是否把list中分配的內存在free后設置成了NULL,杜絕野指針?

void freeList(node **head)
{for (node **cur=head; *cur;){node *entry = *cur;*cur = entry->next;free(entry);entry = NULL; /* is this lie useful? avoid wild pointer ?*/}
}

A: No, 內存free后并沒有被置為NULL.?

其實在循環過程中,*head(也就是*cur) 一直在鏈表中后移,最后指向了最后一個node的next 指針,也就是為NULL。

所以在這個函數執行完后,list的首節點指向了NULL(最后一個node的next 指針),而其它的node所分配的內存雖然被free了,但是并沒有設置為NULL。這樣做也沒有問題,list暴露給用戶的就是head 指針,非head節點并沒有提供給用戶,沒有置為NULL,也就沒有什么問題了。

總結

以上是生活随笔為你收集整理的二维指针操作链表的全部內容,希望文章能夠幫你解決所遇到的問題。

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