2009-12-01 267 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)

(最后一颗子弹点并不意味着你永远使用指针,你只是不使用它们时,这些集装箱是比较合适的。)