[英]Difference between struct * and struct ** in function header
我正在嘗試解決我在C語言中的作業,該作業要求我創建一個函數,該函數將char值放在已排序的鏈表中的正確位置。 實際上,在使它成為struct typedef name *struct
和struct typedef name **struct
之間,函數頭之間並沒有真正的區別。
當我查看老師的解決方案時,她使用**
,並且不了解其含義。
void insert_in_sorted_list(Node *lst, char x) {
Node *temp;
while (lst) {
if (x > lst->value && x < lst->next->value) {
temp = (Node*)malloc(sizeof(Node));
temp->value = x;
temp->next = lst->next;
lst->next = temp;
}
else lst = lst->next;
}
}
考慮它的簡單方法是* <something>
表示指向某物的指針,而'**`表示指向某物的指針。
由於c是按值傳遞的,因此“更改”參數的唯一方法是將指針傳遞給它。
因此,帶有**的函數將更改指針在函數中指向的內容。
如果將結構傳遞給函數,則由於每個函數都會復制一個副本,因此無法更改原始數據。 因此,通常您將指針傳遞給該結構,這意味着您所做的任何更改都將應用於原始數據。 即,您不更新按值副本,而是就地更新舊的內存結構。
但是,有時還沒有結構(例如,因為您想在函數中構造一個結構),因此無法告訴調用方將此新結構放在何處。 因此,您必須傳遞**
說“我已經創建了這個結構,並且它在這里”,然后將該位置傳遞給調用方。 也就是說,您指向創建該結構的內存,然后通過“指針指向”參數技巧將該位置傳遞回去。
您不能簡單地傳遞一個指向該結構的指針,因為它是通過值(即復制)傳遞給函數的。 因此,當函數退出時,將保留舊的指針值。 因此,指針到指針。
指針在概念上很笨拙,恕我直言,認為它們的最佳方法是將其作為包含內存位置(即它們實際所在的位置)的整數值,而不是嘗試將它們理解為某種抽象概念。 那也可以幫助我們理解性能和內存復制等內容。
當您接受帶*
的參數時,您實際上是在接受指向某物的地址(這稱為指針)。 如果您接受帶有**
的參數,則表示您接受的是指向指針的指針。
所以這:
void insert_in_sorted_list(Node *lst, char x)
正在接受指向Node
的指針
和這個:
void insert_in_sorted_list(Node **lst, char x)
正在接受指向Node
的指針。
如果我們已經創建了一個列表,並且沒有添加到列表的前面或后面,那么您的實現將起作用。 但是請考慮如果您需要更改列表中的第一項,可能會發生什么。 如果用戶有一個指向列表中第一個節點的指針並將其傳遞給函數,而新節點需要插入到第一個節點的前面,則該函數可以將其正確地插入到第一個節點的前面,但是當用戶查找時使用此功能后,在列表中,它們仍將具有指向該相同Node
的指針(不再是第一個),並且不知道該節點之前存在一個節點。 因此,用戶將需要將指向第一個節點的指針傳遞給指針,這樣就可以更改指向第一個Node
的指針。
更新代碼以接受指向Node
的指針的指針,現在您需要使用*lst
而不是lst
訪問指向節點的指針
void insert_in_sorted_list(Node ** lst, char x)
要考慮的另一件事是,如果用戶的列表為空,則不會插入任何內容。
考慮一下如果到達最后一個節點(即lst->next
為NULL)會發生什么,當我們嘗試訪問lst->next->value
我們將lst->next->value
某種NULL指針異常。 即使我們不將此代碼末尾插入另一個節點?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.