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?
This question is related to
c
arrays
struct
initialization
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 };
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.
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
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.
It's a designated initializer, introduced with the C99 standard; it allows you to initialize specific members of a struct or union object by name. my_data
is obviously a typedef for a struct
type that has a member name
of type char *
or char [N]
.
Source: Stackoverflow.com