c 结构体的初始化,包括联合

问题描述

我想用以下值初始化以下结构的 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_sizemodel,但我不知道如何设置联合值)或使用 {{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 greenblue 字段位于名为 rgb 的联合体中的结构体 data 中。如果您有一个名为 ColourModelData 的类型为 colourModelData 的变量,您可以像这样设置它的 RGB:

colourModelData.data.rgb.red = 0;
colourModelData.data.rgb.green = 0;
colourModelData.data.rgb.blue = 0;