有什么不同?指向数组与常规数组的指针

时间:2011-05-25 09:15:32

标签: c++ c

我熟悉Java并试图自学C / C ++。我正在从托管材料here的课程中窃取一些课程。不幸的是,我不能问老师,因为我不在课堂上。我关注的是“动态声明的数组”下的部分:

  

如果你   希望能够改变大小   你的数组在运行时,然后声明   动态数组。完成这些   指针和新的运算符。为了   指针上的基础知识,阅读指针   部分。

     

使用new分配内存,然后   您以相同的方式访问该数组   你会是一个静态数组。例如,

     

int * arrayPtr = new int [10];对于   (int i = 0; i< 10; i ++){         arrayPtr [i] = i; }

     

存储器图片与   静态数组,但你可以改变   大小如果你需要。别忘了你   必须先取消分配内存   分配新内存(或者你会   有内存泄漏。)

     

delete [] arrayPtr; // []   删除数组指针时需要   arrayPtr = new int [50]; 。 。

     

当你完全完成了   数组,你必须删除它的内存:

     

delete [] arrayPtr;

     

动态多维数组是   以类似于Java的方式完成。您   将指向指针。为   例如,见

我的理解是C中的数组只是对数组中第一个元素的内存地址的引用。

那么,int *pointerArray = new int[10];int array[10];之间有什么区别?

我做了一些测试,似乎表明他们完全一样。网站是错的还是我读错了?

#include <cstdlib>
#include <iostream>

using namespace std;

int main(int argc, char** argv) {

    // Initialize the pointer array
    int *pointerArray = new int[10];
    for (int i = 0; i < 10; i++){

        pointerArray[i] = i;
    }

    // Initialize the regular array
    int array[10];
    for (int i = 0; i < 10; i++){

        array[i]= i;
    }

    cout << *(pointerArray + 5) << endl;
    cout << *(array + 5) << endl;

    cout << pointerArray[5] << endl;
    cout << array[5] << endl;

    cout << pointerArray << endl;
    cout << array << endl;

    return 0;
}

输出:

5
5
5
5
0x8f94030
0xbfa6a37c

我试图按照网站上的描述“动态地重新调整”指针数组的大小,但是我的新(更大)指针数组最终填充了0,这不是很有用。

9 个答案:

答案 0 :(得分:16)

int array[10];静态地声明数组大小,这意味着它是固定的 - 这是唯一的主要区别。它也可能被分配在函数的堆栈框架内,即在程序的堆栈中。您不必担心在这种数组上使用delete [],事实上,如果delete它可能会导致程序崩溃。

使用operator new时,您可以动态分配内存较慢,内存通常来自而不是程序的堆栈(尽管不是总是)。在大多数情况下这是更好的,因为堆栈空间比堆空间更有限。但是,当您不再需要时,必须注意内存泄漏和delete[]内容。

关于你的数组被零填充,你的课程材料没有说的是你必须这样做:

int *arr = new int[20]; // old array
//do magic here and decide that we need a bigger array
int *bigger = new int[50]; // allocate a bigger array
for (int i = 0; i < 20; i++) bigger[i] = arr[i]; // copy the elements from the old array into the new array
delete[] arr;
arr = bigger;

该代码将数组arr扩展了30多个元素。请注意,您必须将旧数据复制到新数组中,否则它将不存在(在您的情况下,所有内容都变为0)。

答案 1 :(得分:6)

  

我的理解是C中的数组只是对数组中第一个元素的内存地址的引用。

     

那么,int * pointerArray = new int [10]之间的区别是什么?和int数组[10];如果有的话?

你提到的是在任何C / C ++初学者中引起很多混淆的原因。

在C / C ++中,数组对应的内存块足以容纳其所有元素。这与[]语法相关联,如示例所示:

int array[10];

C / C ++的一个特性是您可以通过使用指向其类型的指针来引用数组。因此,您可以写:

int* array_pointer = array;

与:

相同
int* array_pointer = &array[0];

这允许以通常的方式访问数组元素:array_pointer[3], 但是你不能将array视为一个指针,比如在它上面做指针算术(即数组++失败)。

也就是说,您可以在不使用[]语法的情况下管理数组,只需使用malloc分配数组,然后将它们与原始指针一起使用即可。这就是C / C ++的“美”。

恢复:必须区分指针和它指向的内存(实际数组):

  1. 声明中的[]语法(即int array[10];)同时引用两个方面(它给出了指针和数组);

  2. 当声明一个指针变量(即int* p;)时,你只需得到指针;

  3. 在评估表达式时(例如int i = p[4];array[4];),[]仅表示取消引用指针。

  4. 除此之外,int *pointerArray = new int[10];int array[10];之间的唯一区别是前者是动态分配的,后者是堆栈。

答案 2 :(得分:3)

动态分配:

int * pointerArray = new int[10]; 

[顺便说一句,这是一个指向10个int数组的指针,而不是指针数组]

静态分配(可能在堆栈上):

int array[10]; 

否则它们是相同的。

答案 3 :(得分:3)

来自Java时理解C / C ++数组的问题是C / C ++区分数组变量和用于存储数组内容的内存。这两个概念都很重要且不同。在Java中,您实际上只是对一个数组对象的引用。

您还需要了解C / C ++有两种分配内存的方法。可以在帮助或堆栈上分配内存。 Java没有这种区别。

在C和C ++中,数组变量是指向数组第一个元素的指针。数组变量可以存在于堆或堆栈中,包含其内容的内存也可以存在。他们可能是不同的。您的示例是int数组,因此您可以将数组变量视为int*

int *pointerArray = new int[10];int array[10];之间存在两个差异:

第一个区别是包含第一个数组内容的内存是在上分配的。第二个阵列更棘手。如果array是函数中的局部变量,则其内容在堆栈上分配,但如果它是类的成员变量,则在分配包含对象的任何位置(堆或堆栈)分配其内容。 / p>

第二个区别是,正如您所知,第一个数组是动态的:它的大小可以在运行时确定。第二个数组是固定的:编译器必须能够在编译时确定它的大小。

答案 4 :(得分:2)

首先,我会寻找其他学习C ++的地方。您引用的页面是 非常混乱,与实际编程的方式关系不大 在C ++中。在C ++中,大多数情况下,您使用std::vector作为数组, 不是您引用的页面上提出的复杂解决方案。在实践中, 你永远不会使用operator new[](数组new)。

事实上,std::vector在某些方面更像ArrayList而非简单 Java中的数组;与Java中的数组不同,您可以简单地增加向量 通过在其中插入元素,最好是在最后。它支持 迭代器,尽管C ++迭代器与Java有很大不同 迭代器。另一方面,您可以使用[]访问它 运算符,就像普通数组一样。

您引用的页面上描述的数组通常称为C样式 阵列。在C ++中,它们的使用主要限于具有静态的对象 一生,虽然偶尔会出现在课堂上。无论如何,它们永远不会动态分配。

答案 5 :(得分:0)

主要区别在于数组上不允许指针允许的某些操作。

答案 6 :(得分:0)

一方面:

int ar[10];

正在使用堆栈上分配的内存。您可以将其视为本地可用,并且可以将指针/引用传递给其他函数,一旦内存超出范围,内存将被释放(在主示例结尾的示例中,但通常是不是这样的。)

另一方面:

int ar* = new int[10];

为堆上的数组分配内存。它在您的整个程序退出或使用

删除之前可用
delete[] ar;

请注意,对于删除,您需要“[]”,当且仅当相应的新手也拥有它们时。

答案 7 :(得分:0)

存在差异,但在您指向的区域中没有。 *pointerArray将指向大小为10字节的内存块的开头。 array也是如此。唯一的区别是它存储在内存中的位置。 pointerArray是动态分配的内存(在run-time),因此将在堆上,而array[10]将在compile-time分配,并将转到堆栈。

答案 8 :(得分:0)

通过使用指向其第一个元素的指针,您可以获得大多数数组功能。但是编译器知道静态数组由几个元素组成,最显着的区别是sizeof运算符的结果。

sizeof(pointerArray) = sizeof int*

sizeof(array) = 10 * sizeof int