为了详细说明 Angew 引用有关匿名联合和结构的标准提供的答案,我想提供一个 C 源代码示例,该示例生成的输出显示如何在 astruct
和 aunion
组成的struct
组件中分配值union
。
Angew引用的标准是:
出于名称查找的目的,在匿名联合定义之后,匿名联合的成员被认为是在声明匿名联合的范围内定义的。
由命名和匿名结构和联合组成的源代码struct
如下所示。这是使用 Visual Studio 2005 并#pragma (pack, 1)
用于对齐char
边界上的所有内容,以便没有内存漏洞。还定义了一个简单的 C 预处理器宏,以使输出更清晰且更易于编码。
typedef unsigned char UCHAR;
// use of Microsoft Visual Studio pragma to force char alignment for the struct.
#pragma pack(push, 1)
const struct {
union {
const UCHAR myArray[]; // this array shares memory with struct following
struct {
const UCHAR iOne;
const UCHAR iTwo;
const UCHAR iThree;
}; // anonymous struct accessed by specifying Things.
}; // anonymous union accessed by specifying Things.
// const UCHAR myArray[]; // will cause error - "error C2020: 'myArray' : 'struct' member redefinition"
union {
const UCHAR myArray[]; // this array shares memory with struct following
struct {
const UCHAR iOne;
const UCHAR iTwo;
const UCHAR iThree;
} s; // named struct accessed by specifying Things.u.s
} u; // named union accessed by specifying Things.u
} Things = {1, 2, 4, 8, 9, 10, 22, 23, 24, 25};
#pragma pack(pop)
// a little helper macro to make the output easier to code.
#define PRINTF_VAL(x) printf ("%s %d \n", #x, x)
int itSelf (UCHAR iMask)
{
int iMatch = -1;
int jj = 0;
jj = Things.myArray[0]; PRINTF_VAL(Things.myArray[0]);
jj = Things.myArray[1]; PRINTF_VAL(Things.myArray[1]);
jj = Things.myArray[2]; PRINTF_VAL(Things.myArray[2]);
jj = Things.myArray[3]; PRINTF_VAL(Things.myArray[3]);
jj = Things.myArray[4]; PRINTF_VAL(Things.myArray[4]);
jj = Things.iOne; PRINTF_VAL(Things.iOne);
jj = Things.iTwo; PRINTF_VAL(Things.iTwo);
jj = Things.iThree; PRINTF_VAL(Things.iThree);
jj = Things.u.myArray[0]; PRINTF_VAL(Things.u.myArray[0]);
jj = Things.u.myArray[1]; PRINTF_VAL(Things.u.myArray[1]);
jj = Things.u.myArray[2]; PRINTF_VAL(Things.u.myArray[2]);
jj = Things.u.myArray[3]; PRINTF_VAL(Things.u.myArray[3]);
jj = Things.u.myArray[4]; PRINTF_VAL(Things.u.myArray[4]);
jj = Things.u.s.iOne; PRINTF_VAL(Things.u.s.iOne);
jj = Things.u.s.iTwo; PRINTF_VAL(Things.u.s.iTwo);
jj = Things.u.s.iThree; PRINTF_VAL(Things.u.s.iThree);
return iMatch + 1;
}
此函数生成的输出如下所示:
Things.myArray[0] 1
Things.myArray[1] 2
Things.myArray[2] 4
Things.myArray[3] 8
Things.myArray[4] 9
Things.iOne 1
Things.iTwo 2
Things.iThree 4
Things.u.myArray[0] 8
Things.u.myArray[1] 9
Things.u.myArray[2] 10
Things.u.myArray[3] 22
Things.u.myArray[4] 23
Things.u.s.iOne 8
Things.u.s.iTwo 9
Things.u.s.iThree 10
输出显示了 main 的各个组件之间的重叠,这struct
是Things
由使用联合引起的。您还可以查看匿名struct
和union
的组件与命名struct
和的组件是如何被引用的union
。
const UCHAR myArray[];
也只是为了好玩,我尝试在匿名union
包含之后添加一个数组定义,const UCHAR myArray[];
看看会发生什么。编译器报错error C2020: 'myArray' : 'struct' member redefinition
. struct
添加在上面的定义中被注释掉Things
。然而,由于第二次使用const UCHAR myArray[];
是在一个命名union
的编译中,因为第二次使用是通过指定联合的名称来访问的。