【转】结构struct 联合Union和枚举Enum的细节讨论
结构struct 联合Union和枚举Enum的细节讨论
联合(Union)
是一种构造数据类型,它提供了一种使不同类型数据类型成员之间共享存储空间的方法,同时可以实现不同类型数据成员之间的自动类型转换。联合体对象在同一时间只能存储一个成员的值。
联合的内存大小取决于其中字节数最多的成员,而不是累加,联合也会进行字长对齐。在定义联合变量的时候可以指定初始值,但是只能制定一个初始值(测试过似乎无法设置初值),而且该初始值的类型必须与联合的第一个成员的类型匹配。可以取一个联合变量的地址,也可以取变量中的任一个成员的地址,它们总是相等的。可以在同类型的联合变量之间赋值,但是不能比较两个联合变量的大小,不只是因为可能存在填补字节的问题,而且这两个变量可能是不同类型的成员,因此代表了两个类型不同的变量。
有这么几种定义联合体的方法:
1)标准方法
1 union a 2 { 3 int b; 4 char c; 5 }; 6 a abc; 7 abc.b=4; 8 abc.c=5; 9 //或者也可以直接在定义时定义变量 10 union a 11 { 12 int b; 13 char c; 14 }abc; 15 abc.b=4; 16 abc.c=5;
2)使用typedef。这样相当于重新定义一个自定义类型,a作为类型名称。而不是如上面的变量名称。
typedef union { int b; char c; }a; a abc; abc.b=4; abc.c=5;
3)不定义类型而只定义实例名称。这种方法用来局部使用union,而已在指定的某个作用域下使用。此时abc只是变量名称,而不是类型名称。
1 union 2 { 3 int b; 4 char c; 5 }abc; 6 abc.b=5; 7 abc.c=6;
4)匿名联合体(anonymous union),这种联合体比较特殊,它既不定义类型名称,也不定义变量名称。这种联合体只能作用在struct内部,相当于结构的一个成员。
1 struct a 2 { 3 int b; 4 union 5 { 6 int c; 7 char d; 8 }; 9 }; 10 a abc; 11 abc.b=5; 12 abc.c=6; 13 abc.d=7;
这里有一种利用联合体来判断平台属性的简单程序,可以快速地判断平台是大端还是小端模式。如果函数返回0则表示平台是大端模式,否则是小端模式。
1 int CheckCPU(void) 2 { 3 union w 4 { 5 int a; 6 char b; 7 }c; 8 c.a = 1; 9 return(c.b==1); 10 }
1 union U { 2 struct { 3 int a; 4 double b; 5 }; 6 struct { 7 char* c; 8 unsigned d; 9 }; 10 };
枚举(Enum)
定义的一组特殊用途的符号常量,它表示这种类型的变量可以取值的范围。
定义枚举类型的时候,如果不特别指定其中的标示符的值,则第一个标示符的值将是0,后面的比前面的依次大1。如果指定了某一个标示符的值,后面的再前面的基础上依次大1。如
enum Week{Sun, Mon=125, Tue, Wed, Thu=140, Fri, Sat};
其中的符号常量的值依次为:0, 125, 126, 127, 140, 141, 142。
也可以把某些枚举常量初始化为相等的常量,如
enum ABC{A=1, B=1, C=100};
另外,枚举类型还可以是匿名的,即匿名枚举(anonymous enum)。匿名的枚举类型就相当于直接定义的const符号常量,可以作为全局枚举,也可以放在任何类定义或名字空间中。
1 enum 2 { 3 OBJECT_CREATIONG =0x10; 4 OBJECT_DELETIONG =0x11; 5 STATE_CHANGE =0x12; 6 ATTR_VALUE_CHANGE =0x13; 7 };
它可以取代宏常量和const符号常量。(以后看见这样的枚举类型就不会再觉得奇怪了)