简体   繁体   中英

Array of struct initialization in C

I cannot find the solution to this. I can initialize an array of struct like this:

typedef struct S_A {
    int x;
} T_A;

T_A ta1[3];

ta1[0] = (T_A){0};
ta1[1] = (T_A){1};
ta1[2] = (T_A){2};

T_A ta2[3] = { {0}, {1}, {2} };

But how can I do a one-line initialization after declaration?

T_A ta3[3];

ta3 = (?){ {?}, {?}, {?} };

ta3 = (T_A[3]){ { 0 }, { 1 }, { 2 } }; // error
ta3 = (T_A*)  { { 0 }, { 1 }, { 2 } }; // error

Arrays are special in C. You can only once initialize arrays. You can't then "re-initialize" arrays. Assignments on arrays don't work. Array is in most contexts a pointer that you can't assign to. You can't:

int arr[3];
// arr = {1,2,3}; // will not work
// arr = anything; // will not work

You only can memcpy to them with a compound literal:

memcpy(ta3, (T_A[3]){ { 0 }, { 1 }, { 2 } }, sizeof(ta3));

Or without compund literal initialize a temporary variable and memcpy :

const T_A temp[3] = { { 0 }, { 1 }, { 2 } };
memcpy(ta3, temp, sizeof(ta3));

In C, an initialization is something that you do simultaneously as the declaration. You cannot do it afterwards.

This can be seen in the grammar that you can find here: https://www.lysator.liu.se/c/ANSI-C-grammar-y.html

Whenever you use the = after you have finished the declaration, it's an assignment and not an initialization, and assignments have different rules. One of these rules is that the common way of initializing arrays - = {1,2,3} - simply is not allowed. You have to use memcpy or something like that.

When it comes to nonarrays, like int , double etc and their pointers, it is still true that you cannot formally initialize them after declaration, but for those, assignment has the same syntax so it can be confusing.

However, there is a trick that can be used for arrays. Wrap the array in a struct and do like this:

struct wrapper{
    int arr[3];
} x;

x = (struct wrapper){{1,2,3}};

Unfortunately, as others already mentioned, one cannot assign anything to an array.

int arr[N];
...
arr = ... ; // --> This will always fail compilation

The only option is such case is either to assign new value to each array entry separately

arr[i] = ...;

Or use memcpy to copy values from other memory location.

The interesting thing is that if one defines a struct of array(s) rather than an array of struct(s):

typedef struct S_S {
    int x[3];
} T_S;

then the assignment after the declaration is allowed:

typedef struct S_S {
     int x[3];
} T_S;

int main(void)
{
   T_S y;

   y = (T_S){.x = {1, 2, 3}}; //OK!

  return 0;
}

This perfectly compiles (assuming your compiler supports C99 standard)!

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