2009-12-01 269 views
3

的陣列我注意到這一點已經引起了混亂幾個人,但閱讀此一對夫婦的帖子和CPLUSPLUS教程我的大腦還在炒後。C++ - 指向數組的指針 - 指針

假設我有一個頭文件中的下列變量 -

int numberOfLinePoints; 
D3DXVECTOR3* line; //confused as to what it is 

然後在實現C++文件I初始化它們如下 -

//both initialized in constructor 
numberOfLinePoints = 25; 
line = new D3DXVECTOR3[numPoints]; //array of pointers? 

是什麼我行變量現在代表什麼呢?

據我可以從閱讀計算器它應該代表指針數組鏈接告訴。然後我讀然而下面...

(1)Pointers for Beginners

...其中(A)陣列指針,並(B)指向數組的指針,都討論。這讓我再次感到困惑,因爲他們似乎同樣工作。

事實上,我將我的指針定位在一個獨立的位置,我分配的位置(正確?)似乎是我的困惑所在。 我是正確,這是一個指針到D3DXVECTOR3對象的數組?

要完成 - 如果變量線保存關於一個線段信息,我將如何創建線段數組?我目前有以下 -

//HEADER FILE 
int numberOfLineSegments; 
D3DXVECTOR3** lineCollection; //array of pointers - each of which 
           //points to an array of pointers? 
//CPP FILE 
numberOfLineSegments = 8;       //constructor 
for(i = 0; i < numberOfLineSegments; i++)   //initialization 
{             //and allocation CORRECT? 
    lineCollection[i] = new D3DXVECTOR*[numPoints]; //of memory for  Y/N 
}             //lineCollection 

VOID createLineSegments(startPoint, endPoint) //could return array instead 
{ 
//pseudo to generate one line segment 
while != numberOfLinePoints 
line[sentinel++] = interpolate(startPoint, endPoint, time_T) 

//pseudo to generate array of line segments 
while != numberOfLines 
lineCollection[sentinel++] = line 
} 

任何幫助,非常感謝。

+1

你從來沒有在頭文件中的變量聲明存儲。您的「HEADER FILE」行必須全部位於CPP文件的頂部。標題用於聲明事物存在的抽象潛力,而不是實際的存儲空間,或它們在實際程序中被使用或存在的現實情況。 – Mordachai 2009-12-01 21:45:26

+0

我不知道。在我的課程中,我總是被教導對象聲明放在對象頭部,並在CPP文件中初始化。我會帶着我的一位導師,謝謝。 – 2009-12-01 22:10:03

回答

3
int numberOfLinePoints; 
D3DXVECTOR3* line; //confused as to what it is 
//both initialized in constructor 
numberOfLinePoints = 25; 
line = new D3DXVECTOR3[numPoints]; //array of pointers? 

lineD3DXVECTOR3陣列。但是,如果D3DVECTOR3本身就是一個指針,那將是一個指針數組。由於我不太瞭解C++ D3D標題,所以我不確定。

D3DXVECTOR3** lineCollection; 

是一個指針數組,每個指針有可能是一個指針的線(即,D3DXVECTOR3陣列)。

您有兩種選擇。內存方面,最好的做法是將lineCollection中的每個條目設置爲指向相應的行。如果您知道線條不會改變(並且不會被釋放),或者如果它們發生變化,您希望將這些變化直接反映到收藏中,這是安全的。

另一種選擇是爲lineCollection中的每個條目創建一個新陣列,並將每個line中的點複製到這個新陣列中。

沒有正確的答案,它取決於你想要的功能。

+0

感謝Donnie,這正是我想知道的。所有其他答覆也有幫助,但這可能是我能理解的最清楚的方式。 – 2009-12-01 22:13:21

2
D3DXVECTOR3 line; // Line is a D3DXVECTOR3 
D3DXVECTOR3 * line; // Line is EITHER a pointer to D3DXVECTOR3 OR an 
        // array of D3DXVECTOR3 
D3DXVECTOR3 ** line; // Line is an array of pointers to D3DXVECTOR3 OR 
        // an array of array of D3DXVECTOR3 

這是因爲數組在內存中沒有特定的結構。它只是一連串的D3DXVECTOR3。所以指向第一個元素,並且可以訪問所有其他元素。

因此,擁有

D3DXVECTOR3** lineCollection; // An array of pointers OR an array of array! 
new D3DXVECTOR[numPoints]; // A pointer to an array of D3DXVECTOR 
lineCollection[i] // A pointer to an array 

您可以通過初始化:

lineCollection[i] = new D3DXVECTOR[numPoints]; // No extra * 

然而:儘量使用STL(比如std ::向量),而不是醜陋的C/Java的風格數組。如果可以,避免宣佈在堆上(使用「新」),而是宣佈在棧上:

D3DXVECTOR a, b, c; // a, b, and c ARE D3DXVECTOR, not pointers 
std::vector<D3DXVECTOR> lines; 
lines.push_back(a); 
lines.push_back(b); 
lines.push_back(c); 

// equivalently: (you can push_back without temporaries) 
std::vector<D3DXVECTOR> lines; 
lines.push_back(D3DXVECTOR()); 
lines.push_back(D3DXVECTOR()); 
lines.push_back(D3DXVECTOR()); 

這樣可以避免手動內存管理;它更具可讀性。您可能無法始終使用這種舒適(您的代碼組織方式)。如果有人說什麼表演,現在不要擔心。首先得到一些沒有段錯誤或內存泄漏的工作。

+0

如果程序行爲沒有改變,AFAIK編譯器可以決定在堆棧上分配對象,即使在使用新的時候也是如此。只是一個側面說明。 – 2009-12-01 22:05:58

+0

我錯過了這篇文章。其實這與Donnie's一起幫助很大。恥辱我無法設定兩個正確的答案。謝謝。 – 2009-12-01 22:16:50

+0

快樂它可以幫助。 @Space_cowboy:我對編譯器優化知之甚少,我正在尋找一些很好的術語來明確地說明兩種分配方式,因爲我對程序員更感興趣。堆和堆棧會混淆新用戶(顯然也是先進的)。這裏有什麼建議嗎? – 2009-12-01 22:48:40

1
line = new D3DXVECTOR3[numPoints]; 

line保持D3DXVECTOR3的陣列的第一個元素的存儲器地址。

I.e.line是指向數組的第一個元素的指針。

This article應該澄清它。

+0

感謝您的鏈接。 – 2009-12-01 22:14:25

0

只要看看這個簡單的例子:

殼體1:

int *p = new int [N]; 

這裏p是指針N個整數且p存儲從數組的地址的數組。

殼體2:

int **p = new int *[N]; //p is a pointer to pointers holding integers used for 2D array. 


for(int i=0 ; i<N ; i++) 
{ 

    p[i] = new int [N]; // each element is pointer to array of integers. 

} 

它適用於各種用戶定義的類型。

4

你的第一個例子:

int numberOfLinePoints; 
D3DXVECTOR3* line; //confused as to what it is 

聲明一個簡單的指針D3DXVECTOR3。指針可以用兩種方式初始化。第一個:

line = new D3DXVECTOR3; 

這會創建一個單獨的D3DXVECTOR3並使行指向該對象。第二:

line = new D3DXVECTOR3[numberOfLinePoints]; 

這產生D3DXVECTOR3s的陣列,並且使得線指向該陣列的第一個元素。然後可以使用指針算術來訪問該數組中的其他元素。

如果你聲明的指針作爲雙指針:

D3DXVECTOR3** line; 

您只需創建間接的另一個層次。

3

(嘗試以不引入其它問題儘量簡潔地回答問題的第一部分。)

C++(和C)使用指針中的單個項目陣列中的作爲全陣列的手柄。但是,有些指針並不指向數組中的項目!您必須自己區分點對單個項目和點對項目。

int length = 8; 
D3DXVECTOR3* line = new D3DXVECTOR3[length]; 

新[]操作返回指向它分配在陣列中的第一項,而這將該值分配給線。請注意,因爲指針不作單項的區別與項目式陣列:

  • 你必須單獨的存儲長度
  • 你必須要小心你使用正確的指數使用指針(上面的 「線」)
  • 你最好使用一個 「真正的」 容器的類型,如:
    • 的std ::雙端隊列,性病::矢量等
    • 的std :: tr1 ::陣列(又名boost :: array)

(最後一顆子彈點並不意味着你永遠使用指針,你只是不使用它們時,這些集裝箱是比較合適的。)