【问题标题】:Equality & assignment operators used on arrays in C++C++ 中用于数组的等式和赋值运算符
【发布时间】:2011-07-17 18:31:43
【问题描述】:

我收到了一个让我非常困惑的家庭作业问题。问题是:

在 C++ 中,相等测试 == 可能是 应用于数组,但赋值 运算符 = 不能应用于 数组。解释原因。

这让我很困惑,因为我的理解是 == 运算符只会比较前两个元素的地址(如果两个数组实际上保存在不同的内存位置,当然会有所不同)。而= 运算符,当像array1 = array2; 一样使用时,只会导致array1 指向与array2 相同的内存位置。

我在这里缺少什么?似乎可以使用任一运算符,但两者都不会产生这些运算符通常想要的结果。

【问题讨论】:

  • 有趣的是,== 适用于数组,但不适用于 std::vector!
  • @junjanes: == 确实适用于std::vector。对于数组== 测试身份相等性(左右两侧是否是同一个数组),因为数组的== 确实比较了数组初始元素的地址。当您想要测试数组是否“相等”时,这通常不是您想要的。对于vector== 可以满足您对相等比较的期望:它测试一个vector 中的所有元素是否与另一个vector 中的相应元素相等。
  • 实际上很难解释为什么数组不可赋值。 “因为标准是这样说的”,显然,但他们很容易做到。做出这个决定的原因很古老,AFAIK 类似于:在 C 的初始设计期间,极有可能使数组名称实际上 be 指针,初始化指向自动存储。然后,分配是否应该复制数组或重新定位指针可能会令人困惑,因此不是这样做,而是排除了它,并且排除它的决定卡住了。这是 C++ 作业,还是历史作业? ;-)
  • 想一想,也许它卡住了,因为在 C 中使数组可赋值需要一个额外的规则,即在赋值完成时数组不会衰减到指针,而该规则可能会更复杂一些比现有的非常简单的不会发生衰减的情况。 C89 标准相当简洁。
  • @Steve Jessop:也许还因为数组附加了一些元数据,例如数组大小。给定char a[5]; char b[4]; a = b; 会发生什么? sizeof(a) 是什么?是否应该禁止分配?处理这些问题的最简单方法是确保它们永远不会出现。

标签: c++ arrays operators


【解决方案1】:

我的理解是 == 运算符只会比较前两个元素的地址

这是正确的:如果您使用== 比较两个数组,它将比较数组的地址,因此如果您将数组与自身(或指向同类型)。请参阅下面的说明了解原因。

= 运算符,当像 array1 = array2 一样使用时;只会导致 array1 指向与 array2 相同的内存位置。

这是不正确的,因为数组不是指针array1 不能指向与 array2 相同的内存位置,因为 array1 不是指针,它是一个元素数组。

数组是元素的序列。在大多数情况下,数组的名称被隐式转换为指向其初始元素的指针。这就是为什么您可以执行以下操作:

void f(int*);

int data[10];
int* p = data; // this is the same as 'int* p = &data[0];'
f(data);       // this is the same as 'f(&data[0]);'

array1 = array2; 不起作用,因为数组不可赋值(主要是出于历史原因;我从未听说过不允许使用的令人信服的技术原因:C 中从未允许使用它,而 C 一直存在几十年。在 cmets 和Why does C support memberwise assignment of arrays within structs but not generally? 的答案中有一些讨论。

以下程序将无法编译:

int main() {
    int a[10], b[10];
    a = b;
}

对于“可赋值”数组,您可以使用 Boost (boost::array)、C++ TR1 (std::tr1::array) 或 C++0x (std::array) 中的 array 类容器类。它实际上是一个包含数组的类;它可以被复制,它提供了标准库容器的许多优点以及数组的性能特征以及在需要时将其数据用作数组的能力。

【讨论】:

  • 你是说几十年来 C 已经允许数组赋值了?还是没有?
  • @Adam S:我很抱歉;这有点令人困惑。在 C 语言中是不允许的。
猜你喜欢
  • 2012-11-02
  • 1970-01-01
  • 2013-10-26
  • 1970-01-01
  • 2021-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-11
相关资源
最近更新 更多