2015-09-27 55 views
0

考虑代码:在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

+4

您是指'(*阵列)并[h]'?' – Beta

+2

在C++中,你可以使用std ::阵列<> –

+1

数组是一个别名一个C++中的指针。虽然你可以有一个指向指针的指针,但你真的很希望得到'int * arrayptr = array;' – Davislor

回答

5

就像这样:

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

您应该使用(*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; 
} 
+0

数组不是指向intArray的指针,它是一个指针数组。 –

+0

@LuciaPasarin你是否在我的答案中阅读了这个程序? 'array'不是一个指针数组。 –

+0

对不起,我的评论是在查看代码的最后编辑之前。 –

1
int (*array)[MAX] ; 

此行声明array作为指针MAX整数数组验证。 所以如果你想使用array打印intArray,你可以做这样的事情

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

int(* array)[MAX];'不是一个大小为3的指针数组。array是一个类型为int(*)[MAX]'的指针。大小为3的指针数组是'int * array [MAX];' –

+0

@XiaotianPei对不起。我已更新它。 –

2

在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),我们定义一个指针int命名array。注意:不是指向数组int的指针,而是指向纯int的指针。

在管线(2),我们分配intArray到该指针。现在intArray是一个数组,所以我们如何将它分配给一个指针?那么,神奇的是:如果一个数组用在右值上下文中(即,在需要值的上下文中),那么编译器实际上提供了一个指向第一个元素的指针。也就是说,该行完全等同于

array = &(intArray[0]); 

现在在行(3)我们访问array[h]。也就是说,我们访问指针就好像它是一个数组。那么这里发生了什么?那么,指针被解释为指向数组的第一个元素,并访问该数组的元素h。什么实际上情况是,编译器*(array + h)取代array[h]。也就是说,它对hint的指针取消引用,该指针晚于array

好了,那么你的定义

int (*array)[MAX]; 

吗?那么,正如前面的声明定义了一个指向int的指针,它定义了一个指向数组的指针,即指向int[MAX]的指针。如前所述,这可以指向一个由三个int组成的单个数组,也可以指向这样的数组。现在,当你做了

array = &intArray; 

你将其设置为指向单一阵列intArray

现在在你的输出线,你写道:

*(array[h]) 

那么这里发生了什么?那么,在你有array[h]的圆括号中,也就是说,你已经在指针array上使用了数组下标运算符[]。因此,编译器将访问三个整数数组中三个整数的第h个数组。现在你只有一个int数组,所以只要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; 
+1

从这个答案的长度和主题来看,我完全预料它几乎完全是完全荒谬的废话。我很惊喜。做得好! +1 –