简体   繁体   English

在C ++中初始化指向数组的指针的正确方法?

[英]Correct way to initialize pointer to array in C++ ?

Consider the code : 考虑代码:

const int MAX = 3;
int (*array)[MAX]  ;

int intArray[3] = {30 , 40 , 50};

array = &intArray;
for (int h = 0 ; h < MAX ; h++)
{
    std::cout << *(array[h]) << std::endl;
}

The output is : 输出为:

30
0
3

Clearly something is wrong with the initialization of the array , why do I get 30 , 0 , 3 and not 30,40,50 ? 显然,什么是错的与阵列的初始化,为什么会30 , 0 , 3而不是30,40,50

Just like that: 就像这样:

const int MAX = 3;
int *array;

int intArray[3] = {30 , 40 , 50};

array = intArray;
for (int h = 0 ; h < MAX ; h++)
{
    std::cout << array[h] << std::endl;
}

The handling of built-in arrays in C++ is quite peculiar, especially when considering pointers. C ++中内置数组的处理非常特殊,尤其是在考虑指针时。 A pointer can be seen as one of two things: 指针可以看作是以下两种情况之一:

  • as pointer to a single object 作为指向单个对象的指针
  • as pointer to the first element of an array 作为指向数组第一个元素的指针

So how does this work? 那么这是如何工作的呢? Well, let's start with the definition of your array, and let's define a pointer to the array in the way it is normally done in C++: 好吧,让我们从数组的定义开始,让我们以通常在C ++中完成的方式定义一个指向数组的指针:

const int MAX = 3;
int *array;                           // (1)

int intArray[3] = {30 , 40 , 50};

array = intArray;                     // (2)
for (int h = 0 ; h < MAX ; h++)
{
  std::cout << array[h] << std::endl; // (3)
}

Now what is happening here? 现在这里发生了什么?

At line (1) we define a pointer to int named array . 在第(1)行,我们定义了一个指向名为array int的指针。 Note: Not specifically a pointer to array of int , but a pointer to plain int . 注意:不是专门指向int数组的指针,而是一个指向普通int的指针。

At line (2) we assign intArray to that pointer. 在第(2)行,我们将intArray分配给该指针。 Now intArray is an array, so how can we assign it to a pointer? 现在intArray是一个数组,那么如何将其分配给指针? Well, here comes the magic: If an array is used in an rvalue context (that is, in a context where a value is required), then the compiler actually provides a pointer to the first element. 好吧,这就是魔术:如果在右值上下文中(即在需要值的上下文中)使用数组,则编译器实际上会提供指向第一个元素的指针。 That is, the line is completely equivalent to 也就是说,该行完全等于

array = &(intArray[0]);

Now in line (3) we access array[h] . 现在在第(3)行中,我们访问array[h] That is, we access the pointer as if it were an array. 也就是说,我们就像访问数组一样访问指针。 So what happens here? 那么这里发生了什么? Well, the pointer is interpreted as pointing to the first element of an array, and the element h of that array is accessed. 好了,指针被解释为指向数组的第一个元素,并且访问了该数组的元素h What actually happens is that the compiler replaces array[h] by *(array + h) . 实际发生的是编译器将*(array + h) array[h]替换为array[h] That is, it dereferences a pointer that is h int s later than array . 也就是说,它取消引用的指针是h int总比以后array

OK, so what does your definition 好那你的定义是什么

int (*array)[MAX];

do? 做? Well, just as the previous declaration defined a pointer to int , this defines a pointer to an array of MAX int s, that is, a pointer to int[MAX] . 就像前面的声明定义了一个指向int的指针一样,它也定义了一个指向MAX int s数组的指针,即一个指向int[MAX]的指针。 As before, this can point either to a single array of three int s, or to an array of such arrays. 和以前一样,它可以指向三个int的单个数组,也可以指向此类数组的数组。

Now when you did 现在当你做了

array = &intArray;

you set it to point to the single array intArray . 您将其设置为指向单个数组intArray

Now in your output line you wrote: 现在在您的输出行中写道:

*(array[h])

So what happens here? 那么这里发生了什么? Well, in the parentheses you have array[h] , that is, you've used the array subscript operator [] on the pointer array . 好吧,在括号中有array[h] ,也就是说,您已经在指针array上使用了数组下标运算符[] Therefore the compiler will access the h -th array of three ints in your array of arrays of three ints. 因此,编译器将在您的3个整数数组中访问第3个整数的第h个数组。 Now you only have one array of ints there, so as soon as h > 0 you'll be out of bound. 现在,那里只有一个整数数组,因此,只要h > 0您就会越界。 There's absolutely no way to predict the numbers you'll get there (your program could also just have crashed). 绝对没有办法预测到那里的数字(您的程序也可能已经崩溃)。

However we're not yet finished: Your full expression reads *(array[h]) , so you actually dereference the result of array[h] . 但是,我们尚未完成:您的完整表达式为*(array[h]) ,因此您实际上取消了对array[h]的结果的引用。 But the result of array[h] is an array of 3 int s! 但是array[h]的结果是3个int s的数组! Well, the dereference operator expects a pointer value , therefore again the array "decays" to a pointer to its first element, and that of course can be dereferenced, giving the first element of the array. 很好,解引用运算符期望一个指针 ,因此数组再次“衰减”到指向其第一个元素的指针,并且当然可以将其解引用,从而得到数组的第一个元素。 Indeed, you could have equivalently written *(array[h]) as array[h][0] . 实际上,您可以等效地将*(array[h])编写为array[h][0]

And this is also the use case of variables of this type: It would normally be used an variables of the form 这也是这种类型的变量的用例:通常使用形式为以下形式的变量

int intArray[3][3] = {{30, 40, 50}, {300, 400, 500}, {3000, 4000, 5000}};

where you would initialize the pointer with array = intArray and then your loop would output 您将使用array = intArray初始化指针,然后循环输出

30
300
3000

OK, but how would you access the values of your intArray with only three values? 好的,但是如何只用三个值访问intArray值呢? Well, for that you have to first dereference the pointer in order to get to the array, and then access the array index operator: 好吧,为此,您必须首先取消引用指针才能到达数组, 然后访问数组索引运算符:

std::cout << (*array)[h] << std::endl;

Alternatively you can see it as the first (and only) row of a 1×3 array, and equivalently write 或者,您可以将其视为1×3数组的第一行(也是唯一行),并等效地写入

std::cout << array[0][h] << std::endl;
int (*array)[MAX]  ;

This line declare array as pointer to array of MAX integers. 此行将array声明为指向MAX整数数组的指针。 so if you want to print intArray using array , you can do something like this 因此,如果要使用array打印intArray ,可以执行以下操作

for (int h = 0; h < MAX; h++)
    {
        std::cout << (*array)[h] << std::endl;
    }

You should use (*array)[h] . 您应该使用(*array)[h] array is a pointer to the intArray , you should dereference it first. array是一个指向intArray的指针,您应该首先取消引用它。

Since someone thinks that array is of array type which is completely wrong. 由于有人认为array属于数组类型,这是完全错误的。 you can verify with the program 你可以用程序验证

#include <type_traits>
#include <iostream>
using namespace std;
int main() {
  cout << is_array<int*[3]>::value << endl;
  cout << is_array<int(*)[3]>::value << endl;
  return 0;
}

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

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