2017-02-19 230 views
4

隨着我繼續學習C語言,我有了疑問。使用數組中的每個元素是一個結構並使用一個數組中的每個元素都是指向相同類型的結構的指針之間的區別。在我看來,你可以同時使用兩者(儘管在指針中你必須處理內存分配)。有人可以解釋我在哪種情況下最好使用其中一種?結構體數組與指向結構體的指針數組

謝謝。

+3

一個示例:使用'qsort'對指針數組進行排序可能比對結構數組進行排序更快(如果結構體非常大),因爲交換兩個指針會比交換兩個結構更快。 – user3386109

+3

^OTOH,在結構數組上的順序傳遞將更加緩存友好,並且不需要在每一步都有額外的間接尋址。 – StoryTeller

+1

我不認爲這個問題過於寬泛:每種方法的優缺點都存在某種程度的個人意見,但問題在於真正的詢問,並列出兩種解決方案的相關特徵似乎是可行的。 – chqrlie

回答

4

結構和指向結構的指針數組的數組是不同的方式來組織內存。結構的

陣列具有這些長處:

  • 很容易在一個步驟struct s *p = calloc(n, sizeof(*p));分配動態這種陣列。
  • 如果數組是封閉結構的一部分,則根本不需要單獨的分配代碼。本地和全局陣列也是如此。
  • 陣列是一個連續的內存塊中,一個指針到下一個和前元件可以很容易地計算爲struct s *prev = p - 1, *next = p + 1;
  • 訪問數組元素的成員可能更快,因爲它們是在存儲器緊密,提高高速緩衝存儲器的效率。

他們也有缺點:

  • 數組的大小必須明確傳遞,因爲沒有辦法從指針數組有多少元素已經告訴。
  • 表達p[i].member產生一個乘法,這可能是在某些體系結構昂貴,如果結構的大小不是2
  • 改變元素的順序的功率是昂貴的,因爲它可能涉及複製大量的存儲器。

使用指針的陣列具有以下優點:

  • 陣列的尺寸可以通過分配額外的元素並將其設置爲NULL來確定。該慣例用於提供給main()函數的argv[]命令行參數數組。
  • 如果不使用上述約定,並且元素的數量分開傳遞,則可以使用指針值指定缺少的元素。
  • 只需移動指針即可輕鬆更改元素的順序。
  • 可以使多個元素指向相同的結構。
  • 重新分配數組更容易,因爲只有指針數組需要重新分配,可選地保留單獨的長度和大小計數以最小化重新分配。增量分配也很容易。
  • 表達式p[i].member生成一個簡單的移位和額外的存儲器訪問,但可能比結構數組的等效表達式更有效。

和以下缺點:

  • 分配和釋放這種間接陣列更繁瑣。需要額外的循環來分配和/或初始化由數組指向的結構。
  • 對結構元素的訪問涉及額外的內存間接尋址。如果多個成員在同一個函數中訪問,編譯器可以爲此生成高效代碼,但並非總是如此。
  • 指向相鄰結構的指針不能從指向給定元素的指針派生。

EDIT:作爲暗示由David保齡球,可以通過分配的結構的一方面的陣列,並且指向所述第一數組的元素的指針的一個單獨的陣列結合一些的這兩種方法的優點。這是一種實現排序順序的方便方法,甚至可以使用單獨的指針數組(如數據庫索引)實現多個伴隨排序順序。