Reputation: 173
I would like to initialize the ColourModelBlock
of the following struct(s) with the following values:
extension_size = 4
model = 0
red = 0
green = 0
blue = 0
typedef struct {
int extension_size;
ColourModelData ext;
} ColourModelBlock;
typedef struct {
unsigned int model;
union {
struct {
int red; /* % */
int green; /* % */
int blue; /* % */
} rgb;
struct {
int cyan; /* % */
int magenta; /* % */
int yellow; /* % */
int key; /* % */
} cmyk;
struct {
int hue; /* angle (degrees) */
int saturation; /* % */
int value; /* % */
} hsv;
char bytes[16];
int words[4];
} data;
} ColourModelData;
The task seems simple but I tried to set the values directly (which worked for extension_size
and model
but I didn't know how to set the union values) or by using memcpy
of a int
array.
But I am quite new to C so I just may have messed it up.
Upvotes: 1
Views: 60
Reputation: 222457
First, you must declare ColourModelBlock
before you use it in defining ColourModelBlock
.
Then, there are several choices about how to initialize a ColourModelBlock
. First, to initialize structures, you can just list their values in braces. When unions are involved, the first member of the union is initialized:
ColourModelBlock x = { 4, { 0, {{ 0, 0, 0 }} } };
Here the inner braces follow the structure of ColourModelBlock
, using a {
for each contained struct
or union
. The compiler will accept the code without those braces and initialize in the same order, but it may warn you, and it is better to use the braces as it will help catch errors.
Second, you can use member names to indicate which member you are initializing with each value. This would also allow you to initialize unions via a member other than the first, although that is not done here:
ColourModelBlock x = {
.extension_size = 4,
.ext = {
.model = 0,
.data.rgb = { 0, 0, 0 }
}
};
Note the above actually uses a combination of methods. Most members are initialized by name, called a designated initializer. But .data.rgb
names a union and then initializes its members with a list, as in the first method. That may be natural in this case where the rgb
member is thought of as a triple.
You can also define an object and then give it values using assignment statements. The syntax above is for initialization. Assignments require different syntax:
ColourModelBlock x;
x.extension_size = 4;
x.ext.model = 0;
x.ext.data.rgb.red = 0;
x.ext.data.rgb.green = 0;
x.ext.data.rgb.blue = 0;
You can use a compound literal to use the initialization syntax in an assignment. To create a compound literal and use it in an assignment, use any of the initialization lists above and put the type name in parentheses in front of, then use that as the right-hand side of an assignment:
x = (ColourModelBlock) { 4, { 0, {{ 0, 0, 0 }} } };
Finally, since most of the values you want to use as initial values are zero, you can omit them. If a structure is being initialized, and explicit values are not given for all members, the members without explicit values are initialized to zero (or, for pointers, to a null pointer):
ColourModelBlock t = { 4 };
Upvotes: 2
Reputation: 145
The red
green
and blue
fields are inside a struct named rgb
in a union named data
. If you had a variable of type ColourModelData
named colourModelData
you would set its RGB like this:
colourModelData.data.rgb.red = 0;
colourModelData.data.rgb.green = 0;
colourModelData.data.rgb.blue = 0;
Upvotes: 1