此代码无效:
int main() {
int arr1[10];
int arr2[10];
arr2 = arr1;
return 0;
}
但这可行:
struct foo {
int arr[10];
};
int main() {
struct foo f1;
struct foo f2;
f2 = f1;
return 0;
}
但是在我看来,他们做同样的事情:只需将一个数组复制到另一个数组。
答案 0 :(得分:4)
C历史发展的结果是,您不能直接引用数组。
在arr2 = arr1;
中,arr2
和arr1
都命名一个数组。但是C中有一条规则说,当在表达式中使用数组时,它会自动转换为指向带有某些实例的第一个元素的指针。 1 C肯定能够复制一个数组到另一个memcpy(arr2, arr1, sizeof arr2);
。问题在于,根本没有办法在赋值语句中引用数组。
进行数组的这种自动转换是为了方便访问数组元素和以最初开发C语言时使用的方式使用数组。没想到有必要将整个数组作为一个整体对象进行引用,并且为此语言没有内置任何内容。 (即使到今天,也没有必要,除了复制它之外,我们几乎没有要对数组作为单个对象执行的操作。)
早期的C实现也不允许您通过赋值来复制结构。 C是一种相当基本的语言,仅提供简单的操作,而复制整个结构将是一件很花哨的事情。后来,添加了复制结构的功能。
在f2 = f1;
中,f2
和f1
指的是结构,对于数组,也没有规则将它们自动转换为任何东西。
因此,问题仅在于能够表达所需的操作。
1 规则在C 2018 6.3.2.1 3中存在,并且当数组是sizeof
或一元&
的操作数或字符串文字时,例外用于初始化数组(如char x[] = "abc";
- "abc"
是字符串文字,它是数组)。
答案 1 :(得分:1)
这里
int main() {
int arr1[10];
int arr2[10];
arr2 = arr1;
return 0;
}
arr2 = arr1;
不起作用,因为 arr2
是数组,数组名本身就是基地址,即const,您不能更改该地址,即arr2
不能指向任何地址其他地址。通过执行arr2 = arr1;
,您正在尝试更改arr2
的基址。在这里
f2 = f1; /* structure member copy, f2 is structure variable and it can assigned with another structure variable f1 */
f2
是一个结构变量,通过执行f2 = f1;
,f1
成员被复制到f2
中。
但是在我看来,他们做同样的事情:只需将一个数组复制到 另一个数组。
是的,但是编译器不允许执行第一个 arr2 = arr1
,因为您不能在另一个 arr2
中更改基地址em> f2=f1
f1
结构变量成员将被逐个成员复制到f2
成员,并且由于f2
不是数组,因此可能。。
6.3.2.1左值,数组和函数指示符中的段落
- 当说一个对象具有特定类型时,该类型为 由左值指定的用于指定对象。 *一种 可修改的左值是没有数组的左值 类型,没有不完整的类型,没有 const- 限定类型,并且如果是结构或联合,则没有任何类型 成员(包括,递归地,包含的所有成员或元素 const限定类型的聚合或并集。
这里
arr2 = arr1;
左值操作数arr2
不可修改。
另一个关于衰变的段落
- 除非它是 sizeof 运算符, _Alignof 运算符或一元&运算符的操作数,或者是 >字符串常量,用于初始化数组,该表达式具有类型 “ 类型为数组的数组”将转换为具有类型的表达式 “ 要输入的指针”,它指向 数组objec t和不是左值。