C语言 在c中的struct中分配给数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21293491/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 10:40:14  来源:igfitidea点击:

Assign to array in struct in c

carraysgccstruct

提问by Nir

I have the following code:

我有以下代码:

typedef struct Test {
  long mem[1000];
} Test;

extern Test *test;
int main() {
    Test *test =  (Test *)malloc(sizeof(Test)); 
    test->mem[0] = 1;
    test->mem[1] = 2;
    test->mem[2] = 3;
    test->mem[3] = 4;
    test->mem[4] = 5;
    test->mem[5] = 6;
   return 0;
}

It's working OK, but I want to change the initalization of the mem array to be in that way:

它工作正常,但我想将 mem 数组的初始化更改为这种方式:

test->mem = {1,2,3,4,5,6};

But the gcc giving me this error:

但是 gcc 给了我这个错误:

error: expected expression before '{' token test->mem = {1,2,3,4,5,6}; With arrow pointing to the left open braces.

错误:'{' token test->mem = {1,2,3,4,5,6} 之前的预期表达式;箭头指向左边的大括号。

What it can be?

它可以是什么?

Thanks!

谢谢!

EDIT:I also try this code:

编辑:我也试试这个代码:

long mem[1000] = {1,2,3,4,5,6};
    test->mem = mem;

And I'm getting this error from gcc:

我从 gcc 收到这个错误:

error: incompatible types when assigning to type 'long int[1048576]' from type 'long int *' test->mem = mem;

错误:从类型“long int *”分配给类型“long int[1048576]”时类型不兼容 test->mem = mem;

I'm not allow to use any C functions.

我不允许使用任何 C 函数。

回答by Eric Postpischil

The syntax something = { initial values }is allowed only in initializations, where an object is defined, such as:

该语法something = { initial values }仅在定义对象的初始化中允许,例如:

long mem[1000] = { 1, 2, 3, 4, 5, 6 };

An expression such as x = valueis an assignmentand cannot use the syntax for initializations.

例如表达x = value分配而不能使用的语法初始化。

One alternative is to create a temporary object, which you initialize, and then copy the contents of that temporary object into the target:

一种替代方法是创建一个临时对象,您对其进行初始化,然后将该临时对象的内容复制到目标中:

static const long temporary[] = { 1, 2, 3, 4, 5, 6 };
memcpy(test->mem, temporary, sizeof temporary);

Regarding the edit:

关于编辑:

Arrays may not be assigned; x = valueis not valid if xis an array. However, structures may be assigned, so another alternative is to create a structure as a temporary object, initialize it, and assign it:

数组不能被赋值;x = value如果x是数组则无效。但是,可以分配结构,因此另一种选择是创建一个结构作为临时对象,初始化它,然后分配它:

// (After the malloc is successful.)
static const Test temporary = { { 1, 2, 3, 4, 5, 6 } };
*test = temporary;

Note, however, that this code does something the prior code does not. The prior example I showed merely copies six elements into the array. This code creates a temporary object of type Test, which contains 1000 elements, most of them zero, and it copies all of those elements into *test. Even if the compiler optimizes this and uses some code to clear *testrather than actually copying zeroes stored in memory, it takes longer than just copying six elements. So, if you just want a few elements initialized and do not care about the rest, use the former code. If you want all the elements initialized (most to zero), you can use the latter code. (Even so, I would consider alternatives, like using callocinstead of malloc.)

但是请注意,此代码执行了先前代码未执行的操作。我之前展示的示例仅将六个元素复制到数组中。此代码创建了一个类型为 的临时对象Test,其中包含 1000 个元素,其中大部分为零,并将所有这些元素复制到*test. 即使编译器优化了这一点并使用一些代码来清除*test而不是实际复制存储在内存中的零,它也比仅仅复制六个元素花费的时间更长。因此,如果您只想初始化一些元素而不关心其余部分,请使用前面的代码。如果您希望所有元素都初始化(最多为零),则可以使用后一种代码。(即便如此,我也会考虑替代方案,例如使用calloc而不是malloc。)

回答by Basile Starynkevitch

Arrays are not pointers (but arrays decay to pointers, see this), and you cannot assign arrays(only initializethem, or assign struct-s containing them). You could copy the array, e.g.

数组不是指针(但数组衰减为指针,请参阅),并且您不能分配数组(仅初始化它们,或分配struct包含它们的 -s)。你可以复制数组,例如

Test *test =  (Test *)malloc(sizeof(Test)); 
if (!test) { perror("malloc"); exit(EXIT_FAILURE); };
static const int arr[] = {1,2,3,4,5,6};
memcpy (test->mem, arr, sizeof(arr));

BTW, you could copy without using memcpyby coding your loop for (int i=0; i<6; i++) test->mem[i] = arr[i];....

顺便说一句,您可以memcpy通过编码循环来复制而不使用for (int i=0; i<6; i++) test->mem[i] = arr[i];......

This leaves 9994 integers in testuninitialized; you might want to clear them:

这留下了 9994 个test未初始化的整数;你可能想清除它们:

memset (test->mem+6, 0, 9994*sizeof(int));

or use another forloop.

或使用另一个for循环。

You could also define your initialized structure, e.g.

你也可以定义你的初始化结构,例如

Test mystruct = {0, 2, 4, 6, 8};

then assign it, e.g.

然后分配它,例如

*test = mystruct;

but you cannot assign arrays! Even

但你不能分配数组!甚至

// wrong code, won't compile
int ta[4] = { 0, 1, 2, 3}; // initialization, not assignment
int tb[4] = { 2, 4, 6, 8}; // ditto
int *tp = &ta;
ta = tb; // wrong!
tb = tp; // also wrong

won't compile.

不会编译。

FWIW, C++11has std::arrayto help about that.

FWIW,C++11std::array来帮助解决这个问题。

The §6.5.16.1 Simple assignmentsection of the C11standard (see n1570draft page 102) lists a set of constraints regarding assignment, and array assignment don't fit there. Hence it is forbidden. A rule of thumb is that only scalars (that includes pointers and numerical l-values) or struct-s can appear on the left hand side of an assignment (or be return-ed from a function).

C11标准的§6.5.16.1 简单赋值部分(参见n1570草案第 102 页)列出了一组关于赋值的约束,数组赋值不适合那里。因此是禁止的。一条经验法则是,只有标量(包括指针和数值l 值)或-s 可以出现在赋值的左侧(或从函数中被-ed)。structreturn