问题描述
我想用以下值初始化以下结构的 ColourModelBlock
:
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;
任务看起来很简单,但我尝试直接设置值(适用于 extension_size
和 model
,但我不知道如何设置联合值)或使用 {{1} memcpy
数组的 }。
但我对 C 很陌生,所以我可能把它搞砸了。
解决方法
首先,您必须在定义 ColourModelBlock
之前声明 ColourModelBlock
。
然后,关于如何初始化 ColourModelBlock
有几种选择。首先,要初始化结构,您可以在大括号中列出它们的值。当涉及联合时,联合的第一个成员被初始化:
ColourModelBlock x = { 4,{ 0,{{ 0,0 }} } };
这里的内大括号遵循 ColourModelBlock
的结构,对每个包含的 {
或 struct
使用 union
。编译器会接受没有大括号的代码并以相同的顺序进行初始化,但它可能会警告您,最好使用大括号,因为它有助于捕获错误。
其次,您可以使用成员名称来指示您使用每个值初始化哪个成员。这也将允许您通过除第一个之外的成员来初始化联合,尽管这里没有这样做:
ColourModelBlock x = {
.extension_size = 4,.ext = {
.model = 0,.data.rgb = { 0,0 }
}
};
注意上面实际上使用了方法的组合。大多数成员按名称初始化,称为指定初始化器。但是 .data.rgb
命名一个联合,然后用一个列表初始化它的成员,就像在第一个方法中一样。在将 rgb
成员视为三元组的情况下,这可能很自然。
您还可以定义一个对象,然后使用赋值语句为其赋值。上面的语法用于初始化。分配需要不同的语法:
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;
您可以使用复合文字在赋值中使用初始化语法。要创建复合文字并在赋值中使用它,请使用上面的任何初始化列表并将类型名称放在前面的括号中,然后将其用作赋值的右侧:
x = (ColourModelBlock) { 4,0 }} } };
最后,由于您想用作初始值的大多数值都为零,因此您可以省略它们。如果正在初始化一个结构,并且没有为所有成员提供显式值,则没有显式值的成员将初始化为零(或者,对于指针,为空指针):
ColourModelBlock t = { 4 };
,
red
green
和 blue
字段位于名为 rgb
的联合体中的结构体 data
中。如果您有一个名为 ColourModelData
的类型为 colourModelData
的变量,您可以像这样设置它的 RGB:
colourModelData.data.rgb.red = 0;
colourModelData.data.rgb.green = 0;
colourModelData.data.rgb.blue = 0;