为什么C不能直接分配数组但是可以在结构中分配数组?

时间:2019-08-24 04:20:15

标签: c

此代码无效:

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;
}

但是在我看来,他们做同样的事情:只需将一个数组复制到另一个数组。

2 个答案:

答案 0 :(得分:4)

C历史发展的结果是,您不能直接引用数组。

arr2 = arr1;中,arr2arr1都命名一个数组。但是C中有一条规则说,当在表达式中使用数组时,它会自动转换为指向带有某些实例的第一个元素的指针。 1 C肯定能够复制一个数组到另一个memcpy(arr2, arr1, sizeof arr2);。问题在于,根本没有办法在赋值语句中引用数组。

进行数组的这种自动转换是为了方便访问数组元素和以最初开发C语言时使用的方式使用数组。没想到有必要将整个数组作为一个整体对象进行引用,并且为此语言没有内置任何内容。 (即使到今天,也没有必要,除了复制它之外,我们几乎没有要对数组作为单个对象执行的操作。)

早期的C实现也不允许您通过赋值来复制结构。 C是一种相当基本的语言,仅提供简单的操作,而复制整个结构将是一件很花哨的事情。后来,添加了复制结构的功能。

f2 = f1;中,f2f1指的是结构,对于数组,也没有规则将它们自动转换为任何东西。

因此,问题仅在于能够表达所需的操作。

脚注

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左值,数组和函数指示符中的段落

     
      
  1. 当说一个对象具有特定类型时,该类型为   由左值指定的用于指定对象。 *一种   可修改的左值没有数组的左值   类型没有不完整的类型,没有 const-   限定类型,并且如果是结构或联合,则没有任何类型   成员(包括,递归地,包含的所有成员或元素   const限定类型的聚合或并集。
  2.   

这里

arr2 = arr1;

左值操作数arr2 不可修改

另一个关于衰变的段落

  
      
  1. 除非它是 sizeof 运算符, _Alignof 运算符或一元&运算符的操作数,或者是 >字符串常量,用于初始化数组,该表达式具有类型   “ 类型为数组的数组”将转换为具有类型的表达式   “ 要输入的指针”,它指向   数组objec t和不是左值
  2.