0

C中的数组和结构将数据存储在连续的内存中。那么为什么C不允许使用“=”直接复制数组,因为它允许用于结构。例子:

int a[3] = {1,2,3};
int b[3];
b = a; // why is this not allowed. 

struct book b1, b2;
b1.page = 100;
b1.price = 10.0;

b2 = b1; // Why is this allowed
4

3 回答 3

0

当您键入 :b=a时,编译器希望您将一个数组分配给 b,但a它只是一个指向存储数组第一个元素的位置的指针,因此类型不匹配。这就是为什么printf("%d",*a);会 print 1。至于为什么可以分配结构,是因为b1b2在上面的示例中基本上是数据类型的book变量,并且可以分配变量。分配变量时,内容被复制并且它们不引用相同的内存位置。这示例可能会更清楚地解释我在说什么:

#include<stdio.h>

typedef struct{int a;}num;
int main()
{
    num b,c;
    b.a = 10;
    c=b;
    b.a =11;
    printf("%d\n",(c.a));
    return 0;
}

输出是10。这证明了bc在这个例子中没有指向同一个内存。希望这会有所帮助。

于 2013-08-18T06:44:54.590 回答
0

对于第一个问题

您不能直接写入数组,只能将单个单元格写入数组。您可以使用 for 循环来初始化数组 b 或 memcpy(&b, &a, sizeof b);

使用这些结构,编译器会为您执行 memcpy。

如果我错了,请纠正我。

于 2013-08-18T06:19:50.890 回答
0

赋值要求编译器知道要赋值的任何内容的类型和大小。所以形式的分配

 a = b;

要求编译器知道a和的类型。b如果类型相同(例如,两者ab属于 type int),那么编译器可以通过它认为最有效的任何指令简单地复制b到其中。a如果类型不同,但允许隐式提升或类型转换,则在进行提升后也可以进行赋值。例如,如果a是 类型long并且b是 类型shortb则将被隐式提升为long并且该提升的结果存储在 中a

这不适用于数组,因为数组的大小(计算为其元素的大小乘以元素的数量)不一定是已知的。一个编译单元(又名源文件)可能有一个声明(可能通过包含一个头文件)

 extern int a[];
 extern int b[];

 void some_func()
 {
      a = b;
 }

它告诉编译器ab是 的数组int,但它们将由另一个编译单元定义(包括给它们一个大小)。然后另一个编译单元可以这样做;

 extern int a[];

 int a[] = {3,1,4,2,3};    /*  definition of a */

第三个编译单元可以类似地定义b为 27 个元素的数组。

一旦目标文件被链接到一个单独的可执行文件中,所有编译单元的使用ab在所有编译单元中的使用都是相关联的,并且对它们的所有操作都引用相同的定义。

出现这个问题是因为单独的编译模型是 C 的核心特性。所以编译器在咀嚼上面的第一个编译单元时,没有关于数组大小的信息,因为它看不到其他编译单元,并且需要在不参考错误的情况下成功或诊断错误。由于没有关于第一个编译单元可用的任一数组中元素数量的信息,因此无法计算出从一个数组复制到另一个数组的元素数量。在 C 中对此的处理是分配a = b是函数中的可诊断错误some_func()

有替代方法(并且一些其他编程语言以不同方式处理此类情况),但它们通常与其他权衡相关。

这些注意事项通常不会影响struct类型,因为它们的大小在编译时是已知的。因此,如果ab属于同一struct类型,则分配a = b是可能的 - 并且可以通过(比如说)调用memcpy().

注意:我在上面的解释中故意进行了一些过度简化,例如不考虑具有灵活数组成员的结构的情况(来自 C99)。在不改变核心考虑的情况下,讨论此类案例会使上述讨论更加复杂。

于 2020-06-03T08:57:02.147 回答