简体   繁体   English

C ++ - 指向数组的指针 - 指针数组

[英]C++ — Pointers to Arrays — Arrays of Pointers

I notice this has caused confusion for several people, but after reading a couple of posts on here and the cplusplus tutorial my brain is still scrambled. 我注意到这引起了一些人的困惑,但在阅读了这里的几篇帖子和cplusplus教程后,我的大脑仍然被打乱。

Suppose I have the following variables in a header file - 假设我在头文件中有以下变量 -

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

Then in the implementation C++ file I initialize them as follows - 然后在实现C ++文件中,我将它们初始化如下 -

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

What does my line variable now represent? 我的行变量现在代表什么?

As far as I can tell from reading links on stackoverflow it should represent an array of pointers. 据我所知,通过读取stackoverflow上的链接,它应该代表一个指针数组。 I then read the following however... 然后,我读了以下内容......

(1) Pointers for Beginners (1) 初学者指针

...where (A) arrays of pointers, and (B) pointers to arrays, are both discussed. ...其中(A)指针数组和(B)指向数组的指针都在讨论中。 This left me confused once again as they both seem to work similarly. 这让我感到困惑,因为它们似乎都有类似的作用。

The fact that I define my pointers in a seperate location to where I allocate (correct?) them seems to be where my confusion stems from. 事实上,我在一个单独的位置定义我的指针到我分配的位置(正确吗?)它们似乎是我的困惑所源自的地方。 Am I correct that this is an array of pointers to D3DXVECTOR3 objects? 我是否正确,这是D3DXVECTOR3对象的指针数组?

To finish - if variable line holds information about one line segment, how would I create an array of line segments? 完成 - 如果变量行保存有关一个线段的信息,我将如何创建一个线段数组? I currently have the following - 我目前有以下 -

//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
}

Any help is much appreciated. 任何帮助深表感谢。

Your first example: 你的第一个例子:

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

Declares a simple pointer to a D3DXVECTOR3. 声明一个指向D3DXVECTOR3的简单指针。 A pointer can be initialized in two ways. 指针可以用两种方式初始化。 First: 第一:

line = new D3DXVECTOR3;

This creates a single D3DXVECTOR3 and makes line point to that object. 这将创建一个D3DXVECTOR3并使该行指向该对象。 Second: 第二:

line = new D3DXVECTOR3[numberOfLinePoints];

This creates an array of D3DXVECTOR3s and makes line point to the first element of that array. 这将创建一个D3DXVECTOR3数组,并使行指向该数组的第一个元素。 You can then use pointer arithmetics to access other elements in that array. 然后,您可以使用指针算术来访问该数组中的其他元素。

If you declare you pointer as double pointer: 如果将指针声明为双指针:

D3DXVECTOR3** line;

You simply create another level of indirection. 您只需创建另一个间接级别。

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

line is an array of D3DXVECTOR3 . lineD3DXVECTOR3的数组。 It would be an array of pointers if D3DVECTOR3 is itself a pointer, however. 但是,如果D3DVECTOR3本身就是指针, D3DVECTOR3是一个指针数组。 Since I don't know the C++ D3D headers very well, I'm not sure. 由于我不太了解C ++ D3D标题,我不确定。

D3DXVECTOR3** lineCollection;

Is an array of pointers, each pointer likely being a pointer to a line (that is, an array of D3DXVECTOR3 ). 是一个指针数组,每个指针可能是一条指向一条线的指针(即D3DXVECTOR3的数组)。

You have two options. 你有两个选择。 Memorywise, the best would be to set each entry in lineCollection to just point to the corresponding line. 在Memorywise中,最好的方法是将lineCollection每个条目设置为仅指向相应的行。 This is safe if you either know the lines aren't going to change (and aren't going to be freed), or if they do change you want the changes to be reflected immedaitely inside your collection. 如果您知道线路不会更改(并且不会被释放),或者如果它们确实发生更改,您希望更改能够立即反映在您的集合中,这是安全的。

The other option would be to create a new array for each entry in lineCollection , and copy the points from each line into this new array. 另一种选择是为lineCollection每个条目创建一个新数组,并将每line的点复制到这个新数组中。

There is no correct answer, it depends on the functionality you want. 没有正确答案,这取决于您想要的功能。

(Attempting to answer the first part of the question as succinctly as possible without introducing other issues.) (试图在不引入其他问题的情况下尽可能简洁地回答问题的第一部分。)

C++ (and C) uses pointers to a single item in an array as a handle for the full array. C ++(和C)使用指向数组中单个项的指针作为完整数组的句柄。 However, some pointers don't point to items in an array! 但是,一些指针不指向数组中的项目! You have to make the distinction between points-to-single-item and points-to-item-in-array yourself. 您必须自己区分点到单项和点到项目。

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

The new[] operator returns a pointer to the first item in the array it allocates, and this assigns that value to line. new []运算符返回指向它分配的数组中第一个项的指针,并将该值赋给line。 Notice that because pointers don't make the distinction of single-item vs. item-in-array: 请注意,因为指针不区分单项与数组中的项:

  • you have to store the length separately 你必须分开存放长度
  • you have to be careful you use correct indices with pointers ("line" above) 你必须小心你使用指针正确的索引(上面的“行”)
  • you are better off using a "real" container type, such as: 你最好使用“真正的”容器类型,例如:
    • std::deque, std::vector, etc. std :: deque,std :: vector等
    • std::tr1::array (aka boost::array) std :: tr1 :: array(又名boost :: array)

(The last bullet point doesn't mean you never use pointers, you just don't use them when these containers are more appropriate.) (最后一个要点并不意味着你永远不会使用指针,当这些容器更合适时你就不要使用它们。)

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

This is because an array is no specific structure in memory. 这是因为数组在内存中没有特定的结构。 It is just a bunch of D3DXVECTOR3 in a row. 它只是一堆D3DXVECTOR3连续。 So pointing to the first element, and you get access to all of the others. 因此,指向第一个元素,您就可以访问所有其他元素。

So, having 所以,拥有

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

You initialize it by: 你初始化它:

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

Yet: try to use the STL (like std::vector) instead of ugly C/Java style arrays. 然而:尝试使用STL(如std :: vector)而不是丑陋的C / Java样式数组。 If you can, avoid declaring on the heap (using 'new'), but rather declaring on the stack: 如果可以的话,避免在堆上声明(使用'new'),而是在堆栈上声明:

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());

This will avoid manual memory management; 这将避免手动内存管理; it's more readable. 它更具可读性。 You might not be able to always use that comfort (the way your code is organized). 您可能无法始终使用这种舒适度(代码的组织方式)。 And if someone says something about performances, for now, don't worry. 如果有人对表演有所说明,那么现在就别担心。 First get something working without segfaults nor memory leaks. 首先让一些工作没有段错误或内存泄漏。

line = new D3DXVECTOR3[numPoints];

line holds the memory address of the first element of the array of D3DXVECTOR3. line保存D3DXVECTOR3数组的第一个元素的内存地址。

Ie line is a pointer to the first element of the array. line是指向数组的第一个元素的指针。

This article should clarify it. 这篇文章应该澄清一下。

Just look at this simple example : 看看这个简单的例子:

case 1: 情况1:

int *p = new int [N];

Here p is pointer to array of N integers and p stores starting address of the array. 这里p是指向N个整数数组的指针,p表示数组的起始地址。

case 2: 案例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.

}

It is applicable to all kinds of user defined types. 它适用于各种用户定义的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM