0

我不知道如何破译这个人需要告诉我发生了什么请帮助

typedef struct _ARGBCOLOR {
    union {
        struct {
            BYTE B;
            BYTE G;
            BYTE R;
            BYTE A;
        };
        DWORD ARGB;
    };
} ARGBCOLOR, *PARGBCOLOR;
4

5 回答 5

7

如果您有 ,ARGBCOLOR x;您可以访问 4 个单独的字节作为x.Bx.Gx.Rx.A,或访问 32 位字作为x.ARGB

C标准保证这些将正确覆盖(假设尺寸适合和填充要求不会拧紧狗(不是这里的情况))。但是这个结构显然假设了一个小端系统。

一个额外的复杂因素是工会是匿名的。像这样命名一个联合是很常见的u,但是一些编译器允许内部联合和结构是匿名的,因此它的成员被访问就好像它们在一个级别上(与联合本身处于同一级别)。

我最喜欢做这种覆盖类型的方法是将联合放在最外层。您可以复制kindortype成员,以便在任何地方都可以访问它。但是这种方式消除了使用匿名联合的诱惑(在 Ansi-C 或 C99 中不可用),因为您不需要u中间的虚假成员。

typedef union _ARGBCOLOR {
    //BYTE type;
    struct {
        //BYTE type;
        BYTE B;
        BYTE G;
        BYTE R;
        BYTE A;
    } bytes;
    struct {
        //BYTE type;
        DWORD ARGB;
    } word;
} ARGBCOLOR, *PARGBCOLOR;

由于共同的初始前缀属性,所有三个BYTE type;成员将覆盖相同的内存。

另一个变体是为单个字节创建一个数组。

typedef union _ARGBCOLOR {
    DWORD dword;
    BYTE byte[ sizeof(DWORD)/sizeof(BYTE) ];
} ARGBCOLOR, *PARGBCOLOR;
enum { B,G,R,A };

现在我们不需要两个级别,并且类型双关更明显。

ARGBCOLOR x = { 0x10203040 };
x.byte[B] = 50;
x.byte[G] = 60;
printf("0x%8x\n", x.dword);  // prints: 0x10206050
于 2013-06-17T06:58:41.267 回答
2

它与在联合之外声明结构所做的事情相同,但允许您匿名进行,将结构的成员公开为与其他联合成员相同的范围。您的构造特别允许您执行类似的操作

ARGBCOLOR a;
printf("a = %u.%u.%u.%u or %lu\n", a.B, a.G, a.R, a.A, a.ARGB);

(联合本身让您可以将其视为联合中的一种类型,在这种情况下,您可以将其视为四个 BYTE 值的序列或单个 DWORD 值)

如果您将结构定义提升到联合之外:

struct ARGB_VALUES {
    BYTE B, G, R, A;
};
struct ARGBCOLOR {
    union {
        ARGB_VALUES VALUES; /* My god, how can you tell a type from a member? */
        DWORD ARGB;
    };
};

以前的 printf 必须是:

ARGBCOLOR a;
printf("a = %u.%u.%u.%u or %lu\n", a.VALUES.B, a.VALUES.G, a.VALUES.R, a.VALUES.A, a.ARGB);

注意:您使用的结构定义构造非常陈旧。您可以按如下方式减少它并保存为每个结构/类提供第二个别名,该别名会使您的符号表膨胀:

typedef struct ARGBCOLOR {
    ...
} *PARGBCOLOR;

你这样做的方式相当于:

struct _ARGBCOLOR {}; // First symbol.
typedef _ARGBCOLOR ARGBCOLOR;
typedef _ARGBCOLOR *PARGBCOLOR;
于 2013-06-17T07:49:40.503 回答
1
typedef struct _ARGBCOLOR 
{
    union 
    {
        struct 
        {
            BYTE B;
            BYTE G;
            BYTE R;
            BYTE A;
        };

        DWORD ARGB;
    };
} ARGBCOLOR, *PARGBCOLOR;

如果你仔细观察,你可以在中看到 astruct和 a 。您可以使用 typedefed struct中的任何一个,无论哪个可用DWORDunionARGBCOLOR

于 2013-06-17T07:03:52.070 回答
1

最外面的结构在您的示例中并没有真正有用,但是当它有一个额外的成员称为kind或类似的成员时:

struct ARGBCOLOR {
    uint8_t kind;
    union {
        struct {
            BYTE B;
            BYTE G;
            BYTE R;
            BYTE A;
        };
        DWORD ARGB;
    };
} ARGBCOLOR;

然后根据kind您的值将联合解释为具有成员B、和的结构GDWORD 。RAARGB

编辑:请记住,联合和内部结构等匿名成员仅成为 C11 中 C 标准的一部分。

于 2013-06-17T07:06:09.077 回答
1

在联合中,每个数据成员都从内存中的相同位置开始。与 4个字节DWORD ARGB共享内存位置。因此,联合的大小将为 4 个字节,您可以使用, , , 或(可以修改单个字节而不影响其他字节)struct作为一个整体使用ARGB或逐字节访问它。ARGB

于 2013-06-17T07:09:50.467 回答