2012-11-09 138 views
2

你爲什麼這樣做:爲什麼傳遞指針的指針作爲參數去功能

void f(Struct** struct) 
{ 
    ... 
} 

如果我想結構的一個列表進行操作,是遠遠不夠的Struct*通過?這樣我可以做struct++來解決下一個結構,或者我在這裏很困惑? :)

只有當我想以某種方式重新排列結構列表時,它纔有用嗎?但是,如果我只是閱讀,我沒有看到這一點。

回答

0

您是對的,沒有理由將指針傳遞給指針,除非您的函數用於修改傳入的指針。在訪問數組struct s時,單個間接級別絕對足夠。

+0

我不同意。在假設這一點之前理解數據結構的意圖是很重要的......這是一個可能的答案,並且「沒有理由」這個陳述顯然是錯誤的。 – jheriko

+0

@jheriko這裏沒有「假設」:OP明確指出「我希望在結構列表上操作」,因此意圖非常清楚。如果它是列表清單,我的答案會有所不同。 – dasblinkenlight

2

這取決於你的數據結構是什麼樣子。一般來說

void f(struct s **p) 
{ 
    while (*p != NULL) { 
     /* some stuff */ 
     (*p)++; 
    } 
} 

,使用指針的指針是有用的,只有當你試圖修改指針:假設p是指針的空終止數組struct s,您可以通過它使用循環像這樣運行本身。

+0

這隻適用於假設結構直接放在內存中的假設 – MarcDefiant

+0

@Mogria或者如果結構是鏈接列表中的節點,則只有循環會有所不同。 – Lundin

+0

是啊,對不起我投了票,因爲這是不安全的在大多數情況下,並作出噸的假設。這是假定雙指針不是指向單獨分配實例的指針列表 - 一個相當常見的事件 - 而是一個指向對象列表指針的指針,正如你所說的,只有當你希望調用者得到* p修改後的值。 – jheriko

0

API的創建者可能認爲如果每個函數的第一個參數是相同的,參數列表會更容易記住。

1

如果你想修改傳遞給這個函數的調用者的指針,你通常會這樣做。

因爲一切都按C中的值傳遞,所以傳遞struct*只會傳遞指針的副本,不會修改調用者的指針。爲什麼路過struct *在這個C-FAQ解釋。

如果您不打算修改調用者中的指針,則不需要通過struct **

1

有這類參數的多種用途......已經提到

其中,相當常見的是允許呼叫者使用該功能來修改的指針。最明顯的情況下獲取數據的一些斑點的時候,這裏是......

void getData(void** pData, int* size) 
{ 
    *pData = getMyDataPointer(); 
    *size = getMyDataSize(); 
} 

另一種選擇是,也許是間接的額外層次允許列表以某種方式表現?例如通過使用索引來引用特定元素,他們可以被分配和重新分配,而沒有懸掛指針的風險。

還有一種選擇是列表非常大並且存在於碎片存儲器中,或者被快速訪問以便該列表實際上是分組在一起的幾個較小的列表。這種技術也可以用來'懶洋洋地'分配巨大的數組,例如提供了一個數十億個元素的接口,但隨後按需求分配100k塊,因爲它們是用struct **指向整個事物讀取/寫入的,而每個struct *爲null或指向100k個結構體......

說實話,上下文是非常重要的......也有很多用於三重指針作爲功能參數遵循類似的推理。 (例如,將我提到的第一件事與第二件事或第二件事與第三件事等結合起來)