我熟悉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,这不是很有用。
答案 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 ++的“美”。
恢复:必须区分指针和它指向的内存(实际数组):
声明中的[]
语法(即int array[10];
)同时引用两个方面(它给出了指针和数组);
当声明一个指针变量(即int* p;
)时,你只需得到指针;
在评估表达式时(例如int i = p[4];
或array[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