简体   繁体   中英

Possible to populate an array of structs after declaration?

I'm fairly new to C and was wondering if I could first initialize an array of structs of a set size, and then populate the array with the actual structs after declaration. The snippet of code below presents want I want to do, it should be pretty straightforward.

/* Make rectangle 2D object */
struct two_d_obj rect = {0, 4, {0, 0, 1}, {0, 0}, {0, -20.0}, {{0, 0}, {0.1, 0.1}, {0, 0.1}, {0.1, 0}}};
struct two_d_obj obj_array[25];
obj_array[0] = rect;

However, when trying to compile this code, I get the following errors:

hellomousept2.c:39: error: conflicting types for ‘obj_array’
hellomousept2.c:33: error: previous definition of ‘obj_array’ was here
hellomousept2.c:39: error: invalid initializer

Again, I'm a newbie with C and primarily code in Java, so any help to get me on the right track would be highly appreciated and thanks is given in advance.

EDIT: below is the code for my two_d_obj struct

struct two_d_obj
{
    int iType; /*integer signifying shape of object (0 for rect, 1 for circle) */
    int num_vertices; /* number of vertices contained in the shape */
    double color[3]; /*array containing RGB values signifying color of object */
    double center_pos[2]; /*center position of object */
    double velocity[2]; /*velocity of object */
    double vertex_array[50][2]; /*array of vertice coordinates (read in pairs
                             x coordinate followed by y coordinate)
                             protocol: first pair of coordinates is bottom left
                             vertice, pairs that follow are vertices going
                             counter-clockwise       
                             */
};

Well if it is a struct, you can always do a memcpy

struct two_d_obj rect = { ... };
struct two_d_obj obj_array[25];
memcpy(obj_array,&rect,sizeof(two_d_obj ));

if you want to initialize more array members just loop

for (i = 0; i < 25; ++i)
  memcpy(obj_array + i,&rect,sizeof(rect));

Yes, you can do it. Structs can be passed as arguments to functions, can be returned by functions and can be both L-and R-value to operators.

Yes, you can declare an array and then populate it. Simple example using a simple type:

char str[12];
char str[0] = 'a';

It is also possible to copy the value of compound types via assignment (=):

struct foo {
    int x;
    int y;
};

struct foo A = {
    .x = 1,
    .y = 2
};

struct foo B = A;

A and B will now be two separate structs with the same values. With an array:

struct foo fooray[10];
fooray[0] = A;

You can also do this with initialization:

struct foo fooray[10] = { A };

Meaning, the first element of fooray will equal the pre-defined struct foo A. If you initialize an array this way (partially), the remaining elements of the array will be zero'd out, hence:

struct foo fooray[10] = { { 0, 0 } };
// or more simply:
struct foo fooray[10] = { 0 };

Will be an array with all zero'd elements. Note that most modern OS's will zero stack memory anyway for security reasons, but that is not part of the C standard, whereas using initialization is.

Using a C99 (or later) 'compound literal' allows you to write:

struct two_d_obj obj_array[25];
obj_array[0] = (struct two_d_obj){ 0, 4, {0, 0, 1}, {0, 0}, {0, -20.0},
                                   { {0, 0}, {0.1, 0.1}, {0, 0.1}, {0.1, 0} } };

Syntactically, a compound literal consists of a cast specifying the type and a braced initializer with an initial value appropriate for the type specified in the cast. It can be used wherever a value of the same type is required.

However, your immediate problem is that just before (or perhaps just after) the code in the question, you have also defined obj_array , and you can't define the same name twice in the same scope.

The third line of compiler message is inscrutable. You will learn that the first error at a given line is usually accurate; second and subsequent error messages from the same line (or lines just after the first line with an error) are often just an indication that the compiler got confused because of the first problem and misinterpreted the rest of the line as a result. I suspect the 'invalid initializer' warning fits into that category. We can't be sure because you've not shown both lines 33 and 39 in your code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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