Initializing array of structures

197,013

Solution 1

There's no "step-by-step" here. When initialization is performed with constant expressions, the process is essentially performed at compile time. Of course, if the array is declared as a local object, it is allocated locally and initialized at run-time, but that can be still thought of as a single-step process that cannot be meaningfully subdivided.

Designated initializers allow you to supply an initializer for a specific member of struct object (or a specific element of an array). All other members get zero-initialized. So, if my_data is declared as

typedef struct my_data {
  int a;
  const char *name;
  double x;
} my_data;

then your

my_data data[]={
    { .name = "Peter" },
    { .name = "James" },
    { .name = "John" },
    { .name = "Mike" }
};

is simply a more compact form of

my_data data[4]={
    { 0, "Peter", 0 },
    { 0, "James", 0 },
    { 0, "John", 0 },
    { 0, "Mike", 0 }
};

I hope you know what the latter does.

Solution 2

my_data is a struct with name as a field and data[] is arry of structs, you are initializing each index. read following:

5.20 Designated Initializers:

In a structure initializer, specify the name of a field to initialize with .fieldname =' before the element value. For example, given the following structure,

struct point { int x, y; };

the following initialization

struct point p = { .y = yvalue, .x = xvalue };

is equivalent to

struct point p = { xvalue, yvalue };

Another syntax which has the same meaning, obsolete since GCC 2.5, is fieldname:', as shown here:

struct point p = { y: yvalue, x: xvalue };

You can also write:

my_data data[] = {
    { .name = "Peter" },
    { .name = "James" },
    { .name = "John" },
    { .name = "Mike" }
};

as:

my_data data[] = {
    [0] = { .name = "Peter" },
    [1] = { .name = "James" },
    [2] = { .name = "John" },
    [3] = { .name = "Mike" }
}; 

or:

my_data data[] = {
    [0].name = "Peter",
    [1].name = "James",
    [2].name = "John",
    [3].name = "Mike"
}; 

Second and third forms may be convenient as you don't need to write in order for example all of the above example are equivalent to:

my_data data[] = {
    [3].name = "Mike",
    [1].name = "James",
    [0].name = "Peter",
    [2].name = "John"
}; 

If you have multiple fields in your struct (for example, an int age), you can initialize all of them at once using the following:

my_data data[] = {
    [3].name = "Mike",
    [2].age = 40,
    [1].name = "James",
    [3].age = 23,
    [0].name = "Peter",
    [2].name = "John"
}; 

To understand array initialization read Strange initializer expression?

Additionally, you may also like to read @Shafik Yaghmour's answer for switch case: What is “…” in switch-case in C code

Solution 3

There are only two syntaxes at play here.

  1. Plain old array initialisation:

    int x[] = {0, 0}; // x[0] = 0, x[1] = 0
    
  2. A designated initialiser. See the accepted answer to this question: How to initialize a struct in accordance with C programming language standards

    The syntax is pretty self-explanatory though. You can initialise like this:

    struct X {
        int a;
        int b;
    }
    struct X foo = { 0, 1 }; // a = 0, b = 1
    

    or to use any ordering,

    struct X foo = { .b = 0, .a = 1 }; // a = 1, b = 0
    

Solution 4

It's called designated initializer which is introduced in C99. It's used to initialize struct or arrays, in this example, struct.

Given

struct point { 
    int x, y;
};

the following initialization

struct point p = { .y = 2, .x = 1 };

is equivalent to the C89-style

struct point p = { 1, 2 };

Solution 5

This is quite simple: my_data is a before defined structure type. So you want to declare an my_data-array of some elements, as you would do with

char a[] = { 'a', 'b', 'c', 'd' };

So the array would have 4 elements and you initialise them as

a[0] = 'a', a[1] = 'b', a[1] = 'c', a[1] ='d';

This is called a designated initializer (as i remember right).

and it just indicates that data has to be of type my_dat and has to be an array that needs to store so many my_data structures that there is a structure with each type member name Peter, James, John and Mike.

Share:
197,013
zubergu
Author by

zubergu

Working as automated tests/software developer in mobile telecomunication. I started programming two years ago when I was 27 so I'm a living proof that you don't have to be born with keyboard stuck in your a** and write compiler at the age of 9 to code and love it! First, I started learning how to program with Python. Then switched to C ( still love it the most). Fooled around with Pascal (yeah, I know, but it was fun, though ). A little bit of assembly languages, nothing special. Now learning Java ( mostly for testing purpose ). I'm willing to join non-profit programming projects of any kind in my free time. So if you stumble upon my profile, feel free to leave me a message regarding the subject. I know my english is poor, I'm slowly working on it when I'm not busy programming. Have a nice day.

Updated on October 10, 2020

Comments

  • zubergu
    zubergu over 3 years

    Here's initialization I just found in somebody else's question.

    my_data data[]={
        { .name = "Peter" },
        { .name = "James" },
        { .name = "John" },
        { .name = "Mike" }
    };
    

    I never saw something like this before and can't find explanation how is .name possible to be correct.
    What I'm looking for is how step by step this process goes.

    It looks like it gets:

    1) data;
    2) *data;
    3) (*data).name;
    4) (*data).name="Peter";
    

    Or am I totally wrong?

  • jangorecki
    jangorecki over 5 years
    your examples are about struct, not arrays of structs
  • Dave
    Dave over 5 years
    @jangorecki I decomposed the problem; the first example is about array initialisation and the second is about struct initialisation. Combine the two and you can see how the OP's posted syntax works to initialise an array of structs, which was the question here.
  • jangorecki
    jangorecki over 5 years
    yeah, but "combine the two" is what actually was difficult to achieve... anyway your answer was the most useful for me among many I have seen. Will remove downvote when it will possible.