繁体   English   中英

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

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

考虑代码:

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

输出为:

30
0
3

显然,什么是错的与阵列的初始化,为什么会30 , 0 , 3而不是30,40,50

就像这样:

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

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

现在这里发生了什么?

在第(1)行,我们定义了一个指向名为array int的指针。 注意:不是专门指向int数组的指针,而是一个指向普通int的指针。

在第(2)行,我们将intArray分配给该指针。 现在intArray是一个数组,那么如何将其分配给指针? 好吧,这就是魔术:如果在右值上下文中(即在需要值的上下文中)使用数组,则编译器实际上会提供指向第一个元素的指针。 也就是说,该行完全等于

array = &(intArray[0]);

现在在第(3)行中,我们访问array[h] 也就是说,我们就像访问数组一样访问指针。 那么这里发生了什么? 好了,指针被解释为指向数组的第一个元素,并且访问了该数组的元素h 实际发生的是编译器将*(array + h) array[h]替换为array[h] 也就是说,它取消引用的指针是h int总比以后array

好那你的定义是什么

int (*array)[MAX];

做? 就像前面的声明定义了一个指向int的指针一样,它也定义了一个指向MAX int s数组的指针,即一个指向int[MAX]的指针。 和以前一样,它可以指向三个int的单个数组,也可以指向此类数组的数组。

现在当你做了

array = &intArray;

您将其设置为指向单个数组intArray

现在在您的输出行中写道:

*(array[h])

那么这里发生了什么? 好吧,在括号中有array[h] ,也就是说,您已经在指针array上使用了数组下标运算符[] 因此,编译器将在您的3个整数数组中访问第3个整数的第h个数组。 现在,那里只有一个整数数组,因此,只要h > 0您就会越界。 绝对没有办法预测到那里的数字(您的程序也可能已经崩溃)。

但是,我们尚未完成:您的完整表达式为*(array[h]) ,因此您实际上取消了对array[h]的结果的引用。 但是array[h]的结果是3个int s的数组! 很好,解引用运算符期望一个指针 ,因此数组再次“衰减”到指向其第一个元素的指针,并且当然可以将其解引用,从而得到数组的第一个元素。 实际上,您可以等效地将*(array[h])编写为array[h][0]

这也是这种类型的变量的用例:通常使用形式为以下形式的变量

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

您将使用array = intArray初始化指针,然后循环输出

30
300
3000

好的,但是如何只用三个值访问intArray值呢? 好吧,为此,您必须首先取消引用指针才能到达数组, 然后访问数组索引运算符:

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

或者,您可以将其视为1×3数组的第一行(也是唯一行),并等效地写入

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

此行将array声明为指向MAX整数数组的指针。 因此,如果要使用array打印intArray ,可以执行以下操作

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

您应该使用(*array)[h] array是一个指向intArray的指针,您应该首先取消引用它。

由于有人认为array属于数组类型,这是完全错误的。 你可以用程序验证

#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