为啥数组不是左值? [复制]

Posted

技术标签:

【中文标题】为啥数组不是左值? [复制]【英文标题】:Why are arrays not lvalues? [duplicate]为什么数组不是左值? [复制] 【发布时间】:2015-01-21 01:59:15 【问题描述】:

我了解 C 标准禁止将数组用作(可修改的)左值,即在赋值的左侧:

int lhs[4], rhs[4] = 0, 1, 2, 3;
lhs = rhs;  /* illegal! */

现在,我一直想知道为什么会这样。我可以看到上面的语句(以及写入数组的任何其他赋值)被定义为等同于

memcpy((void *) lhs, (void *) rhs, sizeof(lhs));

并施加确保rhs 对用户足够大的负担,但没有决定应该是这种情况。

然而,一个非常相似的例子确实工作得很好:

struct  int a[4];  lhs, rhs = 0, 1, 2, 3, 4;
lhs = rhs;

只需将数组包装在一个结构中,我们就可以准确地得到上述行为,即赋值lhs = rhs等价于:

memcpy((void *) &lhs, (void *) &rhs, sizeof(lhs));

这种(我觉得)不一致的原因是什么?允许将数组赋值解释为memcpys 有什么问题吗?

【问题讨论】:

这里回答:***.com/a/17691191/14955(向下滚动到 Edit2:真正的原因) 一个数组名一个左值。我认为您要问的是为什么数组不可分配。 可能重复:***.com/q/27881442/827263 @Thilo - “真正的原因”也不能很好地解释这一点。对于大多数处理器,访问数组不需要运行时指针。在编译时,数组的大小(对于 C 的早期版本)和相对(相对于目标文件)位置都是已知的,因此数组可以是可分配的。您可以使用数组定义一个结构作为它的唯一成员,并且该结构是可分配的。早于 C 的其他语言(例如 APL 或 Cobol)允许分配数组,所以我不清楚为什么选择它以 C/C++ 中的方式实现数组。 我觉得“真正的原因”并没有回答我的问题。当然,您不能“覆盖”内存 location(数组可以被解释为它;这似乎与 Ritchie 的直觉有些一致),但您可以写入它的 contents (就像结构一样)。除此之外,很明显,分配给指针 value 是没有意义的(不是双关语),但是 数组不是指针,它们的行为就像它们在某些上下文中一样.为什么你不能将赋值的左侧定义为 not 是这些上下文之一? 【参考方案1】:

C 应该是一种低级语言,不会将潜在的内存或耗时的任务隐藏在简单的语法后面。一个操作员生成一个汇编指令;对于更复杂的东西调用一个函数。在早期的 C 中,你也不能分配结构,也不能在函数之间传递它们(你会传递一个指针)。

编辑:

一个结构是一个值。它的大小是静态的并且在编译时是已知的。一个数组是多个值,大多数数组都是动态分配/重新分配的。它们的大小在编译时是未知的,因此编译器不知道要分配和复制多少内存。

int *a, *b;
a = malloc(/* value based on e.g. user input */);
b = a; /* compile this into what? */

为了使其工作,C 必须在内部将数组的大小与指针或指向的数据一起存储。这个决定留给了程序员

【讨论】:

你所说的“早期C”是什么意思?我知道的每个 C standard 都允许分配结构,因此您的论点不适用于任何可以明智地称为 C 的语言。除此之外,如果后来确实将结构分配添加到该语言中,为什么不包括数组赋值? 关于您的编辑:这不是我正在谈论的一个示例-您的代码甚至不包含数组,而且它可以编译很好(将 pointer a 的值分配给 pointer b)!

以上是关于为啥数组不是左值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥 .length() 不是 Java 中数组的方法? [复制]

为啥一个空数组等于一个空字符串,而不是 javascript 中的另一个空数组? [复制]

为啥带有对象的 typeof 数组返回“object”而不是“array”? [复制]

C:试图将指针值复制到另一个指针中,得到可修改的左值错误

为啥这些代码仍然使用左值函数? [复制]

通过指针表示法写入二维数组