如何将数组赋值给struct member array?

时间:2012-10-31 16:07:01

标签: iphone objective-c ios c

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

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;

6 个答案:

答案 0 :(得分: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.花费了编译代码中的任何内容 - 它们都是说服编译器使用其内置代码的简单方法在数组赋值中。

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

答案 1 :(得分:2)

不能将数组相互分配,也就是说,不允许数组标识符位于赋值的左侧。当在右侧时,数组被称为衰减指向其第一个元素的指针,因此它并不真正代表整个元素。

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

答案 2 :(得分:1)

您正在尝试分配数组,但无法分配数组。 An array is lvaluememcpy

  

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

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

您需要使用{{3}}代替。您应该将sizeof(myStruct.data)作为第三个参数传递给memcpy:

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

答案 3 :(得分:0)

您无法直接指定类似的数组。你必须把它复制过来。

答案 4 :(得分:0)

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

答案 5 :(得分: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"};