【问题标题】:What is the type and address of a static array in C++? [duplicate]C++中静态数组的类型和地址是什么? [复制]
【发布时间】:2014-06-30 21:19:07
【问题描述】:

使用 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 **'

好的,所以我尝试int (*)[3] pb = &b;,但它甚至在语法上都不正确。本地窗口显示 pb 是 int[3],但 int[3]* pb = &b; 也不正确。

bpa 具有相同的值对我来说似乎也很奇怪。如果我将声明 int b[3]; 替换为声明 + 初始化 int b[3] = {};,那么这种奇怪现象就会消失,所以它可能只是一个 VS 错误:

但我仍然无法获取静态数组的地址。如果我在即时窗口中输入&b,那么我得到的输出与我刚刚输入b 完全相同,与明显不同的'&a' 和'a' 相比,这又显得很奇怪:

【问题讨论】:

  • 值得指出的是pb 的声明应该类似于int (*pb)[3] = &b;。您只是将标识符放在错误的位置。

标签: c++


【解决方案1】:

动态数组是 C++ 中一个非常奇怪的部分。它是一种永远不是语言中任何表达式的类型,而且您永远无法将动态数组视为一个整体。当你说new T[N] 时,你得到的只是一个指向T[N] 类型的虚构数组的第一个元素的指针。 (另请注意,这是一个真正的“动态类型”!)

相比之下,您的b 是一个实际的数组对象,因此它的地址自然具有“指向数组的指针”类型。如果你想要一个指向第一个元素的指针,你首先必须创建这样一个指针:

int b[3];
int * b0 = &b[0];  // or just "int * b0 = b;" :-S
int ** pb = &b0;

这里的变量b0 类似于动态示例中的变量a - 一个包含第一个数组元素地址的指针变量。

【讨论】:

  • 那么&a 的类比是什么?这就是我要找的...
  • @GeorgeSkelton: 如果b0a 的类似物,那么&a 的类似物就是&b0...
【解决方案2】:

@Kerrek 说动态数组是 C++ 中奇怪的一部分;我说静态数组很奇怪,它们的语义不同于语言中的其他任何东西。

给定一个数组:

int foo[3] = { 1, 2, 3 };

指向数组的指针:

int (*pfoo)[3] = &foo;

对数组的引用(模板的强大功能令人惊讶):

int (&rfoo)[3] = foo;

指向第一个元素的指针:

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

请注意,衰减指针和指向实际数组的指针具有相同的值,因为它们指向相同的内存位置:

assert((void*)foo == (void*)&foo);

但是对于任何大于 1 的数组大小,这个断言都会失败:

assert((void*)(foo+1) == (void*)(&foo+1));

因为:

static_assert(sizeof(*(foo+0)) == sizeof(int), "");
static_assert(sizeof(*(&foo)) == sizeof(int[3]), "");

无法复制分配:

int bar[3] = foo; // compile error!

...除非它发生在编译器生成的代码中:

struct workaround { int foo[3]; };
workaround a = { { 1, 2, 3 } };
workaround b = a;
assert(b.foo[0] == 1); // the array got copied!

不能是函数的结果:

int (func1())[3]; // syntatically correct, but prohibited by C++

因此必须求助于解决方法:

std::array<int, 3> func2();
void func3( int (&out_arr)[3] );

如果这不奇怪,那我不知道是什么。

(尽管如此,堆栈分配 FTW)。

【讨论】:

  • 谢谢我从中学到了一些好东西
猜你喜欢
  • 2012-09-14
  • 2010-10-25
  • 2014-09-27
  • 2011-03-23
  • 2011-08-13
  • 1970-01-01
  • 2014-08-05
  • 2011-12-17
  • 2023-03-28
相关资源
最近更新 更多