在c ++中声明数组(并为它们分配内存)的两种方法中的2种
1. int a[3];
2. int *b = new int[3];
我想了解c ++如何以不同的方式对待这两者。
一个。在这两种情况下,我都可以使用以下语法访问数组:a[1]
和b[1]
湾当我尝试cout<< a
和cout<< b
时,都会打印相应数组的第一个元素的地址。
在我看来,a和b都被视为指向数组第一个元素的指针。
℃。但奇怪的是,当我尝试cout << sizeof(a)
和sizeof(b)
时,他们分别打印出不同的值 - 分别为4和12。
我不明白为什么在sizeof(b)
的情况下,正在打印整个数组的大小。
答案 0 :(得分:8)
a
是一个数组(类型int [3]
)
b
是一个指针(类型int*
)
在C ++中,它们完全不同。
sizeof
数组是元素的数量乘以每个元素的大小
sizeof
指针独立于数组的大小(通常为4或8个字节)。
数组和指针的唯一共同点是数组在几种情况下经常“衰减”到指针。当你打印出它们的价值时,就会发生这种情况。
答案 1 :(得分:3)
正如您所指出的,似乎,好像a
和b
都是指向数组开头的指针。但实际上,只有b
是一个指针。 a
实际上是一个数组。
在编写(或阅读)代码时,两者之间的差异是微妙的。变量a
被视为常规变量(就像int
或double
),因为它具有分配给它的自动分配的内存部分。为了比较,假设您已声明int i
。变量i
是为内存中的某组连续字节赋予的名称,用于保存整数值(计算机上为4个字节)。类似地,a
是保存数组的连续字节集的名称(在您的情况下为12个字节)。
相反,b
只是指向单个内存位置的指针。在您的情况下,有一个12字节的块,动态分配(通过new int[3]
)。 b
本身是一个自动分配的4字节指针,指向该12字节块中的第一个int
值。
所以他们真的是两种不同的东西。这对C ++程序员来说不太清楚。其中一个原因是您可以在两种类型上使用[]
运算符。另一个原因是数组在几种情况下隐式退化为指针(例如在函数void Foo(int a[3]);
中,a
实际上不是数组,而是指向数组开头的指针。但不要被愚弄 - 数组不是指针(正如许多人所声称的那样),指针绝对不是数组。
答案 2 :(得分:0)
1。堆栈上的数组必须具有编译时已知的大小。
2在堆上分配。堆上的数组没有这样的要求。请记住,如果您使用new[]
分配,则需要稍后使用delete[]
解除分配:
int* b = new int[3];
delete[] b;
答案 3 :(得分:0)
堆栈中的C ++数组有一个限制
int array[10];
sizeof(array) needs to be compile-time constant and
sizeof(array[0])==sizeof(array[1])==...==sizeof(array[9])
堆中的C ++数组只有第二个限制,但不是第一个限制。 (这允许在运行时确定数组大小)
答案 4 :(得分:-1)
堆栈数组(#1)的大小受堆栈限制。 堆数组(#2)的大小受堆的限制(比堆栈大)。
堆栈分配有一些显着的性能优势,请查看此主题以获取更多信息:Which is faster: Stack allocation or Heap allocation