#include<stdio.h>
int main(){
int a[] = {1,2,3};
int b[] = {4,5,6};
b = a;
return 0;
}
导致此错误的结果:
array type 'int [3]' is not assignable
我知道数组是左值且不可赋值,但在这种情况下,编译器只需要重新分配一个指针即可。 b
应该指向 a
的地址。为什么这样做不可行?
b = a;
由于在这里,b
在赋值中被用作左值,因此它被视为int [3]
类型,而不是int *
类型。指针衰减规则对于b
没有影响,只对a
作为右值有效。
在C语言中,无法使用b = a;
将一个数组(这里是b
)通过另一个数组的指向第一个元素的指针(这里是a
)进行赋值。
该语法不允许这样做。
这就是错误信息
"array type 'int [3]' is not assignable"
针对b
的意思。
此外,您似乎误解了指针衰减规则,认为数组被转换为任何方式都可以存储不同对象位置的指针对象。
这是不正确的。这种转换以非常隐式的方式发生,并且是本SO问题的主题:
Is the array to pointer decay changed to a pointer object?
a
中的值赋给数组 b
,则可以使用 memcpy()
函数:memcpy(b, a, sizeof(a));
b
不是指针。当你声明并分配a
和b
时,你得到的是:+---+
| 1 | a[0]
+---+
| 2 | a[1]
+---+
| 3 | a[2]
+---+
...
+---+
| 4 | b[0]
+---+
| 5 | b[1]
+---+
| 6 | b[2]
+---+
没有为任何指针预留空间。数组元素本身就是指针对象,没有单独的指针对象 a
或 b
。
C语言源于一种早期语言叫做B,在B中有一个单独的指向第一个元素的指针:
+---+
b: | +-+--+
+---+ |
... |
+----+
|
V
+---+
| | b[0]
+---+
| | b[1]
+---+
...
+---+
| | b[N-1]
+---+
a [i] == *(a + i)
),但他不想在任何地方存储单独的指针。因此,他创建了以下规则-除非它是sizeof
或一元&
运算符的操作数,或者是用于在声明中初始化字符数组的字符串文字,类型为“N元素数组的T
”的表达式将被转换(“降解”)为类型为“指向T
的指针”的表达式,并且表达式的值将是数组的第一个元素的地址,该值不是lvalue。
这有几个实际影响,其中最相关的是数组表达式可能不是赋值的目标。在大多数情况下,数组表达式失去其“数组性”,并且不像其他类型一样对待。
编辑
实际上,这样陈述是错误的——数组表达式可能不是赋值的目标,因为数组表达式不是可修改的lvalue。降解规则没有发挥作用。但是,语句“数组不像其他类型一样处理”仍然成立。
结束编辑
结果是,您无法仅使用=
运算符将一个数组的内容复制到另一个数组中。您必须使用库函数如memcpy
或逐个复制每个元素。
其他人已经解释了你的错误。我写这篇答案是为了解释实际上 编译器可以将一个数组分配给另一个数组,并且您可以通过对示例代码进行最小更改来实现相同的效果。
只需将您的数组包装在一个结构中。
#include <stdio.h>
int main(){
struct Array3 {
int t[3];
};
struct Array3 a = {{1,2,3}};
struct Array3 b = {{4,5,6}};
a = b;
printf("%d %d %d", a.t[0], a.t[1], a.t[2]);
return 0;
}
x=y
),并暗示“实际上你可以将一个数组分配给另一个”的措辞如果严格理解是不正确的。我指的是措辞,而不是您的回答。如果您编辑掉这部分,我会给您点赞。 - RobertS supports Monica Cellio来自《C程序设计语言》:
数组名是零号元素的地址。
数组名和指针之间有一个必须记住的区别。指针是变量,但是数组名不是变量。
我的理解是数组名是常量,因此不能被赋值。
memcpy
。 - Fiddling Bitsb
:int *b = a;
- Serge