简体   繁体   English

如何将数组分配给结构成员数组?

[英]How to assign an array to struct member array?

How to assign c type array to struct member that is also an array of the same type? 如何将c类型数组分配给也是相同类型数组的struct成员? Here's my struct: 这是我的结构:

typedef struct {

  uint8_t type;
  uint8_t data[10];

} MyStruct;

Here's the creation of the struct: 这是该结构的创建:

MyStruct myStruct;

Here's generation of some array: 这是一些数组的生成:

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

Here's my assignment: 这是我的作业:

myStruct.data = generatedArray;

As other answers have stated an array is not directly assignable and you must use a function such as memcpy : 正如其他答案所指出,数组不能直接分配,您必须使用memcpy的函数:

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

However... 然而...

C is a language with a long history. C是具有悠久历史的语言。 Early languages had roughly the notion of "little" and "large" types, the former being directly assignable and the latter not. 早期语言大致具有“小”和“大”类型的概念,前者可直接分配,而后者则不可。 Some later languages made everything assignable (or for functional languages, values). 某些后来的语言使所有东西都可以赋值(或对于功能语言,取值)。

Original C had primitive types; 原始C具有原始类型; integer, float, etc.; 整数,浮点数等; and arrays of these types. 以及这些类型的数组。 The former, being "little", were assignable, the latter, being "large", were not. 前者“小”是可分配的,后者是“大”,不是可分配的。 Subsequently C gained structures, and decided these were "little"... 随后,C获得了结构,并认为这些结构“很小”。

So, a little strangely, while you cannot directly assign one array to another you can assign on structure to another, and in particular you can assign a structure with just one field which is an array... You can also write literal structure values, including for those with array-valued fields; 因此,有些奇怪,虽然您不能直接将一个数组分配给另一个数组,但是可以在结构上分配给另一个数组,特别是可以分配仅包含一个字段(即数组)的结构。您还可以编写文字结构值,包括那些具有数组值字段的对象; and being C with its "types are comments" approach you can cast a pointer to an array to a pointer to a structure... 并使用“类型为注释”作为C语言,您可以将指向数组的指针转换为指向结构的指针...

The above means you can write "fun" code like: 以上意味着您可以编写“有趣”的代码,例如:

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

Note that none of the casts, indirections, etc. or in the final example the extra array. 注意,没有强制类型转换,间接寻址等,也没有最后一个示例中的额外array. in the indexing cost anything in the compiled code - they are all simply ways to persuade the compiler to use its built-in array assignment. 在索引中,编译后的代码不会花费任何费用-它们都是说服编译器使用其内置数组分配的简单方法。

Many would of course argue against regular uses of these techniques! 当然,许多人会反对定期使用这些技术!

Arrays cannot be assigned to each other, that is, an array identifier is not allowed to be on the left side of an assignment. 数组不能互相分配,也就是说,数组标识符不允许位于分配的左侧。 When on the right side, the array is said to decay to a pointer to its first element, so it doesn't really represent the whole chunk. 在右侧时,据说该数组会衰减到指向其第一个元素的指针,因此它实际上并不代表整个块。

You should use memcpy instead, and pass the size of the array which can be obtained via the sizeof operator. 您应该改用memcpy ,并传递可以通过sizeof运算符获得的数组sizeof For short arrays, an optimizing compiler may be able to substitute the memcpy call with more efficient instructions to exploit the target architecture better. 对于短数组,优化的编译器可能能够用更有效的指令代替memcpy调用,以更好地利用目标体系结构。

You are attempting to assign to an array, but an array cannot be assigned to. 您正在尝试分配给数组,但是无法分配给数组。 An array is , however, an lvalue : 数组是一个左值

The following object types are lvalues, but not modifiable lvalues: 以下对象类型是左值,但不是可修改的左值:

  • An array type 数组类型
  • An incomplete type 不完整的类型
  • A const-qualified type const限定类型
  • An object is a structure or union type and one of its members has a const-qualified type 对象是结构或联合类型,并且其成员之一具有const限定类型

You'll need to use memcpy instead. 您将需要使用memcpy代替。 You ought to pass sizeof(myStruct.data) as the third argument to memcpy: 您应该将sizeof(myStruct.data)传递给memcpy的第三个参数:

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

You can't directly assign an array like that. 您不能直接分配这样的数组。 You'll have to copy it over. 您必须将其复制过来。

I wonder how your compiler let you do that assignment. 我不知道您的编译器如何允许您执行该分配。 You cannot use array as modifiable lvalue . 您不能将array用作modifiable lvalue Also when used as rvalue an array represents a pointer to the first element in the array. 同样,当用作rvalue ,数组表示指向数组中第一个元素的指针。 Other ways of achieving this would be to use pointers or to use memcopy() 实现此目的的其他方法是使用指针或使用memcopy()

With C99 you can use compound literals and string literals as initializer ( if uint8_t has the same bit-representation as char ) 使用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"};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM