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

Initialization of c struct including union

我想用以下值初始化以下结构的 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,但我不知道如何设置联合值)或使用 [= int 数组的 19=]。

但我对 C 还很陌生,所以我可能把它搞砸了。

red greenblue 字段位于名为 data 的联合中名为 rgb 的结构内。如果你有一个名为 colourModelDataColourModelData 类型的变量,你可以这样设置它的 RGB:

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

首先,在定义 ColourModelBlock 时必须先声明 ColourModelBlock

然后,关于如何初始化一个ColourModelBlock有几种选择。首先,要初始化结构,您只需在大括号中列出它们的值。当涉及到union时,初始化union的第一个成员:

ColourModelBlock x = { 4, { 0, {{ 0, 0, 0 }} } };

这里的内括号遵循 ColourModelBlock 的结构,对每个包含的 structunion 使用 {。编译器将接受没有这些大括号的代码并以相同的顺序初始化,但它可能会警告你,最好使用大括号,因为它有助于捕获错误。

其次,您可以使用成员名称来指示您正在使用每个值初始化哪个成员。这也将允许您通过第一个成员以外的成员初始化联合,尽管这里没有这样做:

ColourModelBlock x = {
        .extension_size = 4,
        .ext = {
            .model = 0,
            .data.rgb = { 0, 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, {{ 0, 0, 0 }} } };

最后,由于大多数要用作初始值的值都是零,因此可以省略它们。如果正在初始化一个结构,并且没有为所有成员给出显式值,则没有显式值的成员被初始化为零(或者,对于指针,初始化为空指针):

ColourModelBlock t = { 4 };