关于C#:数组名称不是左值的原因是什么?

Is there a reason why an array name is not an lvalue?

例如,

1
2
3
int x[10];
int i = 0;
x = &i; //error occurs!

根据C-A参考手册,数组名不能是左值。因此,x不能是左值。但是,数组名不能是左值的原因是什么?例如,为什么第三行出现错误?


Array names are non-modificable lvalues in c.:

Arrays are named extents of memory where their elements are placed.所以你不能代替记忆的一个延伸来代替记忆的另一个延伸。一个阵列宣言的每个初始存储器扩展都有其独特的名称。每一个阵列名称都与它自己的存储器扩展相连。


你的参考资料不正确。一个阵列可以是一个LVALUE(但不是一个可更改的LVALUE),而一个"阵列名称"(标识符)总是一个LVALUE。

以你的例子:

1
2
3
int x[10];
int i = 0;
x = &i; //error occurs!

Apply C11 6.5.1,paragraph 2:

An identifier is a primary expression, provided it has been declared
as designating an object (in which case it is an lvalue) ...

我们认为,x是一个基本的表达形式,是一个LVALUE,因为它已经被预先宣布为一个阵列对象。

然而,C语言规定,在各种情况下,包括在分配表达式的左手侧的阵列表达式,被转换成在阵列的第一元素中的点,而不是LVALUE,即使阵列是这样。Specifically:

BLCK1/

(C11 6.3.2.1第3段)。

由于LVALUE设定了一个物体,所以上述特定转换结果的指针不是LVALUE,因此没有一个方便的物体固定指针值;阵列物体固定了阵列中的元素,而不是对这些元素的指针。

例如,在你的问题中,你使用的是一个阵列表达式衰减(被转换为)一个指针值,但我认为,你准确地承认,在转换之后,指针值和阵列是两个不同的东西。指针不是一个LVALUE;该阵列可能是(在你的例子中,它是)。在实例中,无论是LVALUES是LVALUES还是不LVALUES,都没有改变;这是指针值,你试图指定。

如果你要问:为什么当他们在分配操作员的左手边时,阵列会消失?-然后我怀疑没有特别好的答案c/Just doesn't allow assignment to arrays,historically.


事实上,在许多情况下,阵列名称是有效的指针值。但是操作员,你不指望这是可以指定的。

1
2
3
4
5
6
7
int i = 42;
int *j = malloc(sizeof *j);
&i = j; /* obviously wrong */

int a[] = {1,2,3};
&a[0] = j; /* also obviously wrong */
a = j; /* same as the previous line! */

所以当你了解到阵列和指针之间的关系时,记得a通常和&a[0]一样,然后你不认为LVAULUE-NESS是规则的一个例外——它是完美的规则。


一个阵列是一个LVALUE,但它是一个不可改变的LVALUE。

它最喜欢与类型兼容。例如,你可以这样做:

1
2
3
4
5
6
7
8
struct ss {
    char c[10];
};

...

struct ss s1 = { {"hello" } };
struct ss s2 = s1;

但不是这个

ZZU1