2

如何将 c 类型数组分配给同样是同一类型数组的结构成员?这是我的结构:

typedef struct {

  uint8_t type;
  uint8_t data[10];

} MyStruct;

这是结构的创建:

MyStruct myStruct;

这是一些数组的生成:

uint8_t generatedArray[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

这是我的任务:

myStruct.data = generatedArray;
4

6 回答 6

3

正如其他答案所述,数组不可直接分配,您必须使用以下函数memcpy

memcpy(myStruct.data, generatedArray, sizeof(myStruct.data));

然而...

C是一门历史悠久的语言。早期语言大致有“小”和“大”类型的概念,前者可以直接赋值,而后者不能。后来的一些语言使一切都可以分配(或对于函数式语言,值)。

原始 C 有原始类型;整数、浮点数等;和这些类型的数组。前者是“小”,是可分配的,后者是“大”,不是。随后C获得了结构,并认为这些是“小”的......

所以,有点奇怪,虽然您不能直接将一个数组分配给另一个数组,但您可以将结构分配给另一个数组,特别是您可以分配一个只有一个字段的结构,它是一个数组......您还可以编写文字结构值,包括那些具有数组值字段的人;并且作为具有“类型是注释”方法的C,您可以将指向数组的指针转换为指向结构的指针......

以上意味着您可以编写“有趣”的代码,例如:

typedef struct
{
    uint8_t type;
    uint8_t data[10];
} MyStruct;

typedef struct
{
    uint8_t data[10];
} MyArray;

typedef struct
{
    uint8_t type;
    MyArray array;
} MyStruct2;

void arrayAssignment(int x)
{
    MyStruct myStruct;
    MyArray generatedArray = {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}; // structure literal

    *(MyArray *)&myStruct.data = generatedArray;

    uint8_t generatedArray2[] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; // array literal
    *(MyArray *)&myStruct.data = *(MyArray *)generatedArray2;

    MyStruct2 myStruct2;
    myStruct2.array = generatedArray; // no casts at all, but element access is myStruct2.array.data[index]
}

请注意,没有任何强制转换、间接寻址等,或者在最后一个示例array.中,索引中的额外成本在编译代码中没有任何成本——它们都是说服编译器使用其内置数组分配的简单方法。

许多人当然会反对经常使用这些技术!

于 2012-10-31T17:33:40.743 回答
2

数组之间不能相互赋值,即数组标识符不允许出现在赋值的左侧。在右侧时,据说数组衰减为指向其第一个元素的指针,因此它并不真正代表整个块。

您应该memcpy改用,并传递可以通过sizeof运算符获得的数组的大小。对于短数组,优化编译器可能能够memcpy用更有效的指令代替调用,以更好地利用目标架构。

于 2012-10-31T16:09:54.600 回答
1

您正在尝试分配给数组,但无法分配给数组。 然而,数组是一个左值

以下对象类型是左值,但不是可修改的左值:

  • 数组类型
  • 不完整的类型
  • 一个 const 限定的类型
  • 对象是结构或联合类型,其成员之一具有 const 限定类型

您需要改用memcpy。您应该将sizeof(myStruct.data)第三个参数作为第三个参数传递给 memcpy:

memcpy(myStruct.data, generatedArray, sizeof(myStruct.data));
于 2012-10-31T16:11:12.693 回答
0

您不能直接分配这样的数组。你必须把它复制过来。

于 2012-10-31T16:10:20.500 回答
0

我想知道您的编译器如何让您完成该任务。您不能将数组用作modifiable lvalue. 此外,当用作rvalue数组时,表示指向数组中第一个元素的指针。实现这一点的其他方法是使用指针或使用memcopy()

于 2012-10-31T16:12:17.127 回答
0

使用 C99,您可以使用复合文字和字符串文字作为初始值设定项(如果 uint8_t 具有与 char 相同的位表示)

MyStruct myStruct={.data="\1\2\3\4\5\6\7\x8\x9\xa"};
...
MyStruct myStruct;
myStruct = (MyStruct){.data="\1\2\3\4\5\6\7\x8\x9\xa"};
于 2012-10-31T17:01:38.807 回答