2014-07-22 52 views
2

我發現這個鏈接列表例程(來自Haviland的Unix系統編程)將一個項目添加到單個鏈接列表中。頭部指針指針

additem(item **head, item *newitem) 
{ 
    newitem->next = *head; 
    *head = newitem; 
} 

我的難處在於試圖理解item **head部分。 **head究竟意味着什麼?

additem(item *head, item *newitem) 
{ 
    newitem->next = head; 
    head = newitem; 
} 

回答

3

這是一個指針的指針:爲什麼不只是item *head如下定義程序。

在C中,您無法更改通過值傳遞的變量,因爲參數是作爲局部變量處理的。您必須改爲指針,然後修改*variable的值。

當你想改變的變量已經是一個指針時,它也適用。在這種情況下,您必須將指針傳遞給該指針,因此當您更改此指針時,此更改會傳播給調用者。

*head是價值head指向。而head類型爲item **,*head的類型爲item *

當你這樣做:

additem(item *head, item *newitem) 
{ 
    newitem->next = head; 
    head = newitem; 
} 

修改的head的值不會影響它的值給調用者。出於所有目的,在這種情況下更改head是沒有意義的。

0

如果您只是將指針*head傳遞給子例程並更改它的值並嘗試返回它,那麼您會發現不能這樣做,因爲它是一個傳遞給只存在於例程堆棧上的例程的值,只要例程在範圍內。但是,您可以將指針傳遞給該指針(**head,它也將在堆棧中本地),然後更改它指向的值,然後在調用例程的範圍中更改要更改的值實際上已經改變。

這是通過引用實現調用的'C方式',儘管C只正式支持按值調用—它使用值的調用,並且該值的值是對所需對象的引用改變,從而允許通過引用來調用。

1

您的題目中有第一個問題的答案:item **head表示head是指向指針的指針。

爲什麼你的第二個代碼片段不起作用?因爲

head = newitem; 

分配值到當地變量head,這不是什麼代碼打算這樣做。

0

只要明白一點:如果你想要另一個函數來改變一個變量的值。你必須通過它的地址,因爲C使用「按價值調用」機制。

void change_value(type *a) 
{ 
    *a = ...; 
} 

在這種情況下,你想一個指針的值更改爲型(頭*),所以它的地址有頭的類型**

型* 一個等於到(頭*)*一個頭**一個