簡體   English   中英

函數頭中struct *和struct **之間的區別

[英]Difference between struct * and struct ** in function header

我正在嘗試解決我在C語言中的作業,該作業要求我創建一個函數,該函數將char值放在已排序的鏈表中的正確位置。 實際上,在使它成為struct typedef name *structstruct 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是按值傳遞的,因此“更改”參數的唯一方法是將指針傳遞給它。

因此,帶有**的函數將更改指針在函數中指向的內容。

  • struct-是一個占用內存的數據對象。
  • struct *-是指向該內存塊的指針
  • struct **-是指向該內存塊的指針! (是的,現在令人困惑)

如果將結構傳遞給函數,則由於每個函數都會復制一個副本,因此無法更改原始數據。 因此,通常您將指針傳遞給該結構,這意味着您所做的任何更改都將應用於原始數據。 即,您不更新按值副本,而是就地更新舊的內存結構。

但是,有時還沒有結構(例如,因為您想在函數中構造一個結構),因此無法告訴調用方將此新結構放在何處。 因此,您必須傳遞**說“我已經創建了這個結構,並且它在這里”,然后將該位置傳遞給調用方。 也就是說,您指向創建該結構的內存,然后通過“指針指向”參數技巧將該位置傳遞回去。

您不能簡單地傳遞一個指向該結構的指針,因為它是通過值(即復制)傳遞給函數的。 因此,當函數退出時,將保留舊的指針值。 因此,指針到指針。

指針在概念上很笨拙,恕我直言,認為它們的最佳方法是將其作為包含內存位置(即它們實際所在的位置)的整數值,而不是嘗試將它們理解為某種抽象概念。 那也可以幫助我們理解性能和內存復制等內容。

當您接受帶*的參數時,您實際上是在接受指向某物的地址(這稱為指針)。 如果您接受帶有**的參數,則表示您接受的是指向指針的指針。

所以這:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM