您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“C語言中二級指針與鏈表怎么應用”,內容詳細,步驟清晰,細節處理妥當,希望這篇“C語言中二級指針與鏈表怎么應用”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
簡述:其實就是一個指針指向另一個指針的地址。
我們都知道指針指向地址,但是指針自身也是一個變量,當然也可以被二級指針所指向。
語法:形如 int x = 10; int *q = &x; int **p = & q;
那么這里的q指針指向x的地址,p指針指向指針q的地址,*q可以得到x的值,*p可以得到q指針本身,**p也可以得到x的值。
代碼示例:
int main(void) { int x = 10; int* q = &x; int** p = &q; printf("x 的地址為: %d\n", &x); printf("q 指向的地址為:%d\n", q); printf("*p的值為: %d\n", *p); //p指向指針q的地址,那么*p是解引用操作, //就等于了q本身 printf("x 的值為: %d\n", x); printf("q 存取的值為: %d\n", *q); printf("**p的值為: %d\n", **p); //**p相當于解引用解了兩次,第一次先得到q本身, //第二次得到q指向地址的值 return 0; }
運行結果:
這里以帶頭結點的雙鏈表為例
typedef int ElemType;//將整型數據重命名為int typedef int Status;//整型重命名為Status //雙鏈表的數據結構定義 typedef struct DouNode { ElemType data; //數據域 struct DouNode* head; //前驅指針 struct DouNode* next; //后繼指針 }DousList, * LinkList;// 結點指針
代碼解釋:
利用typedef對數據類型進行重命名,只要在后面遇到的 ElemType和 Status都是整型就夠了。雙鏈表結構體包含三個部分:數據域、前驅指針、后繼指針,與單鏈表的區別就是多了一個前驅指針。然后大括號結束部分也是重命名,此時DousList和DouNode效果一樣,都是結構體名,然后LinkList是指向結點的指針。
具體使用:
LinkList L,L是一個指針,DousList *P,P也是一個指針,屬于兩種創建方式。
使用兩種正確的創建鏈表形式和一種錯誤的形式,對比著記憶創建方法
傳入一級指針
這種方式并不能成功創建
代碼演示:
void CreateDouList(LinkList L, int n) { LinkList ptr; int i; L = (LinkList)malloc(sizeof(DousList)); //為頭結點申請空間 L->next = NULL; L->head = NULL; L->data = n;//L->data記錄結點的個數 ptr = L; for (i = 0; i < n; i++) { int value = 0; scanf("%d",&value); LinkList me = (LinkList)malloc(sizeof(DouNode)); me->data = value; //節點數據域 me->next = NULL; me->head = NULL; ptr->next = me; me->head = ptr; ptr = ptr->next; //尾插法建表 } }
代碼解析:
這里的參數列表是 LinkList L 和 整型數據 n,L是傳入的鏈表頭結點指針,n是用來記錄插入數據的個數的,在下面的for循環用做循環的次數。接下來使用malloc函數為L鏈表分配內存空間,malloc需要用指針來接收,左邊的括號是分配的指針類型,右邊的括號是分配的內存空間大小。分配空間完成之后初始化前驅和后繼指針為空,數據域data記錄數據的個數。ptr指針初始等于L指針,接下來進入n次循環,創建待插入結點指針me并進行分配內存空間和初始化,最后三行代碼進行尾插法建立鏈表:
尾插法:
先讓ptr的后繼指針指向me,然后me的head指針指向ptr,這就相當于在鏈表頭把me結點插入鏈表,然后ptr指向這個插入的新結點,這就保證了每次插入的結點都在上一個插入的結點之后。
但是這樣真的在鏈表中插入數據了嗎 ,來看看調試結果:
進入遍歷的程序時,讓創建的ptr指針指向L鏈表的后繼,立馬就出現了空指針異常,但是上面明明插入數據了,原因是什么呢? 很明顯,這里的鏈表L并未完成插入數據。這是因為我們在創建鏈表的函數里傳入的只是鏈表的指針L,那么在函數里這個指針只是一個副本,在這里給他增大內存空間并不會影響到實參鏈表,這和普通數據類型的值傳遞和地址傳遞的情況一致。
我們利用傳入指針地址來解決這個問題,兩個方法:指針的引用和二級指針
傳入指針的引用
函數的實現部分完全不用修改,只要形參列表加上一個引用符"&"即可。
void CreateDouList(LinkList &L, int n);
查看調試結果:
同樣的調試方法,傳入指針的引用之后可以清晰的看到L的data等于5,也就是存了五個數據,然后對于的后繼結點的值都和尾插的結果一致,最后一個結點的后繼指針正好指向NULL,完全符合我們的設計的代碼。
傳入指針的引用之后,函數里鏈表的空間變化會導致實參里的鏈表空間變化,這樣做才能使插入操作完成,將結點插入到鏈表內。
傳入二級指針
這個和指針的引用原理一樣,我主要分享給你們使用的形式
注意調用的時候實參要加“&”符,例:CreateDouList(&L,n);
void CreateDouList(LinkList *L, int n) { LinkList ptr; int i; *L = (LinkList)malloc(sizeof(DousList)); //為頭結點申請空間 (*L)->next = NULL; (*L)->head = NULL; (*L)->data = n;//L->data記錄結點的個數 ptr = (*L); printf("開始插入數據:\n"); for (i = 0; i < n; i++) { int value = 0; scanf("%d",&value); LinkList me = (LinkList)malloc(sizeof(DouNode)); me->data = value; //節點數據域 me->next = NULL; me->head = NULL; ptr->next = me; me->head = ptr; ptr = ptr->next; //尾插法建表 } }
這里形參列表的參數是 LinkList *L,和DousLIst **L效果一樣,是一個二級指針。如果用到指向鏈表的指針就需要一次接引用操作,寫成(*L)的形式。然后再去分配空間、進行初始化、賦值給鏈表指針ptr等操作,這樣鏈表二級指針L的改變也會使實參的鏈表發生改變,可以查看調試結果。
調試結果:
讀到這里,這篇“C語言中二級指針與鏈表怎么應用”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。