你爲什麼這樣做:爲什麼傳遞指針的指針作爲參數去功能
void f(Struct** struct)
{
...
}
如果我想結構的一個列表進行操作,是遠遠不夠的Struct*
通過?這樣我可以做struct++
來解決下一個結構,或者我在這裏很困惑? :)
只有當我想以某種方式重新排列結構列表時,它纔有用嗎?但是,如果我只是閱讀,我沒有看到這一點。
你爲什麼這樣做:爲什麼傳遞指針的指針作爲參數去功能
void f(Struct** struct)
{
...
}
如果我想結構的一個列表進行操作,是遠遠不夠的Struct*
通過?這樣我可以做struct++
來解決下一個結構,或者我在這裏很困惑? :)
只有當我想以某種方式重新排列結構列表時,它纔有用嗎?但是,如果我只是閱讀,我沒有看到這一點。
您是對的,沒有理由將指針傳遞給指針,除非您的函數用於修改傳入的指針。在訪問數組struct
s時,單個間接級別絕對足夠。
這取決於你的數據結構是什麼樣子。一般來說
void f(struct s **p)
{
while (*p != NULL) {
/* some stuff */
(*p)++;
}
}
,使用指針的指針是有用的,只有當你試圖修改指針:假設p
是指針的空終止數組struct s
,您可以通過它使用循環像這樣運行本身。
這隻適用於假設結構直接放在內存中的假設 – MarcDefiant
@Mogria或者如果結構是鏈接列表中的節點,則只有循環會有所不同。 – Lundin
是啊,對不起我投了票,因爲這是不安全的在大多數情況下,並作出噸的假設。這是假定雙指針不是指向單獨分配實例的指針列表 - 一個相當常見的事件 - 而是一個指向對象列表指針的指針,正如你所說的,只有當你希望調用者得到* p修改後的值。 – jheriko
API的創建者可能認爲如果每個函數的第一個參數是相同的,參數列表會更容易記住。
如果你想修改傳遞給這個函數的調用者的指針,你通常會這樣做。
因爲一切都按C中的值傳遞,所以傳遞struct*
只會傳遞指針的副本,不會修改調用者的指針。爲什麼路過struct *
在這個C-FAQ解釋。
如果您不打算修改調用者中的指針,則不需要通過struct **
。
有這類參數的多種用途......已經提到
其中,相當常見的是允許呼叫者使用該功能來修改的指針。最明顯的情況下獲取數據的一些斑點的時候,這裏是......
void getData(void** pData, int* size)
{
*pData = getMyDataPointer();
*size = getMyDataSize();
}
另一種選擇是,也許是間接的額外層次允許列表以某種方式表現?例如通過使用索引來引用特定元素,他們可以被分配和重新分配,而沒有懸掛指針的風險。
還有一種選擇是列表非常大並且存在於碎片存儲器中,或者被快速訪問以便該列表實際上是分組在一起的幾個較小的列表。這種技術也可以用來'懶洋洋地'分配巨大的數組,例如提供了一個數十億個元素的接口,但隨後按需求分配100k塊,因爲它們是用struct **指向整個事物讀取/寫入的,而每個struct *爲null或指向100k個結構體......
說實話,上下文是非常重要的......也有很多用於三重指針作爲功能參數遵循類似的推理。 (例如,將我提到的第一件事與第二件事或第二件事與第三件事等結合起來)
我不同意。在假設這一點之前理解數據結構的意圖是很重要的......這是一個可能的答案,並且「沒有理由」這個陳述顯然是錯誤的。 – jheriko
@jheriko這裏沒有「假設」:OP明確指出「我希望在結構列表上操作」,因此意圖非常清楚。如果它是列表清單,我的答案會有所不同。 – dasblinkenlight