使用Visual Studio Express 2013.我以为我理解静态与动态数组,但以下让我困惑:
int* a = new int[3]; \\ dynamic array
int** pa = &a;
int b[3]; \\ static array
int** pb = &b; \\ error: cannot convert from 'int (*)[3]' to 'int **'
Run Code Online (Sandbox Code Playgroud)
好吧,所以我尝试int (*)[3] pb = &b;但它甚至在语法上都不正确.本地窗口说pb是一个int[3],但int[3]* pb = &b;也是不正确的.

它似乎也奇怪,我b有相同的值pa.如果我用int b[3];声明+初始化替换声明int b[3] = {};那么奇怪就会消失,所以也许它只是一个VS错误:

但我仍然无法获得静态数组的地址.如果我输入&b立即窗口然后我得到完全相同的输出,就像我刚输入一样b,与'&a'和'a'相比,这看起来很奇怪,这些明显不同:

动态数组是C++的一个非常奇怪的部分.它是一种永远不会是语言中任何表达式的类型,并且您永远不会看到动态数组作为一个整体.当你说new T[N],你得到的只是一个指向虚构数组类型的第一个元素的指针T[N].(另请注意,这是一个真正的"动态类型"!)
相比之下,你b是一个实际的数组对象,所以它的地址自然就是"指向数组的指针".如果你想要一个指针指向它的第一个元素,你首先必须创建这样一个指针:
int b[3];
int * b0 = &b[0]; // or just "int * b0 = b;" :-S
int ** pb = &b0;
Run Code Online (Sandbox Code Playgroud)
TBE可变b0这里是您的变量的类似物a在动态例如-包含第一阵列元素的地址的指针的变量.
@Kerrek 说动态数组是 C++ 的奇怪部分;我说静态数组很奇怪,它们的语义与语言中的其他任何东西都不同。
给定一个数组:
int foo[3] = { 1, 2, 3 };
Run Code Online (Sandbox Code Playgroud)
指向数组的指针:
int (*pfoo)[3] = &foo;
Run Code Online (Sandbox Code Playgroud)
对数组的引用(模板的功能非常强大):
int (&rfoo)[3] = foo;
Run Code Online (Sandbox Code Playgroud)
指向第一个元素的指针:
int *pa = &foo[0];
assert(*pa == 1);
int *pb = foo; // auto decay!
assert(pa == pb);
assert(pa == foo); // auto decay strikes again
assert(pa+0 == foo+0); // and again
Run Code Online (Sandbox Code Playgroud)
请注意,衰减到指针和指向实际数组的指针具有相同的值,因为它们指向相同的内存位置:
assert((void*)foo == (void*)&foo);
Run Code Online (Sandbox Code Playgroud)
但对于任何大于 1 的数组大小,此断言将失败:
assert((void*)(foo+1) == (void*)(&foo+1));
Run Code Online (Sandbox Code Playgroud)
因为:
static_assert(sizeof(*(foo+0)) == sizeof(int), "");
static_assert(sizeof(*(&foo)) == sizeof(int[3]), "");
Run Code Online (Sandbox Code Playgroud)
复制分配是不可能的:
int bar[3] = foo; // compile error!
Run Code Online (Sandbox Code Playgroud)
...除非它发生在编译器生成的代码中:
struct workaround { int foo[3]; };
workaround a = { { 1, 2, 3 } };
workaround b = a;
assert(b.foo[0] == 1); // the array got copied!
Run Code Online (Sandbox Code Playgroud)
不能是函数的结果:
int (func1())[3]; // syntatically correct, but prohibited by C++
Run Code Online (Sandbox Code Playgroud)
因此,人们必须采取解决方法:
std::array<int, 3> func2();
void func3( int (&out_arr)[3] );
Run Code Online (Sandbox Code Playgroud)
如果这都不奇怪,那我就不知道什么才是了。
(尽管如此,堆栈分配 FTW)。