二、位段
2.1 位段的含义
位段和结构的定义类似但有两个不同:
1.位段的成员必须是int、unsigned int 、signed int或char类型。
2.位段的成员名后有一个冒号和一个数字。
struct A1//结构体 { int a; int b; int c; int d; }; struct A2//位段 { int a:2; int b:5; int c:10; int d:30; };
输出
输出不一样的原因是:struct A1中每个成员为整型,默认的分配4个字节,那么struct A1总体的大小为16个字节,而struct A2中每个成员后的数字是其大小,单位是bit,也就是说a大小为2个比特位,b大小为5个bit位,c大小为10个bit位,d大小为30个bit位,struct A2总体大小为47个bit位,也就是8个字节(1字节=8bit位)。
2.2 位段的内存分配
1.位段的成员可以是 int、 unsigned int、 signed int 或者是 char (属于整形家族)类型。
2.位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
3.位段涉及很多不确定因素,位段是不跨平台的,注意可移植的程序应该避免使用位段。
2.3 位段跨平台问题
1.int 位段被当成有符号数还是无符号数是不确定的。
2.位段中最大位的数目不能确定。
16位机器最大16,32位机器最大32,写成27,在16位机器会出问题。
3.位段中的成员在内存中是从左向右分配,还是从右向左分配的标准还未定义。
4.当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时, 是舍弃剩余的位还是利用,这是不确定的。
注意:与结构相比,位段可以达到同样效果,并且可以节省空间,但是有跨平台问题。
三、枚举
枚举就是一一列举,将可能取值都列举出来。例如:星期数只有周一到周日7天,性别只有男 和女等例子都是可一一列举的,可以使用枚举。
3.1 枚举定义
enum DAY//星期,枚举类型 { Mon, //枚举常量 Tues, //枚举常量 Wed, //枚举常量 Thur, //枚举常量 Fri, //...... Sat, Sun }; enum sex//性别 { male, female };
这些枚举常量都有值,默认从0开始,依次增加1,而且我们也可以定义时赋初值
enum color//颜色 { red=1, blue=2, green=3 };
3.2 枚举优点
1.增加代码的可读性和可维护性。
2.和#define定义的标识符比较,枚举有类型检查,更加严谨。
3.便于调试。
4.使用方便,一次可以定义多个常量。
3.3 枚举使用
enum color//颜色 { red=1, blue=2, green=3 };//只能拿枚举常量给枚举变量赋值。
四、联合
4.1 联合的定义
联合是一种特殊的自定义类型,此类型定义的变量也包含一系列成员,特点是这些成员公用同一块空间,故联合也称共用体。
#include<stdio.h> //联合类型的声明 union Un { char c; int i; }; int main() { //联合变量的定义 union Un un; //计算联合变量的大小 printf("%d\n", sizeof(un)); }
4.2 联合的特点
联合的成员共用一块空间,不同时使用,联合变量的大小至少是最大成员的大小,因为联合至少得有能力保存最大的成员。
#include<stdio.h> //联合类型的声明 union Un { char c; int i; }; int main() { union Un un; printf("%d\n", &(un.i)); printf("%d\n", &(un.c)); un.i = 0x11223344; un.c = 0x55; printf("%x\n", un.i); }
输出
4.3 联合大小的计算
联合的大小至少是最大成员的大小。
当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。l
#include<stdio.h> union Un1 { char c[5]; int i; }; union Un2 { short c[7]; int i; }; int main() { printf("%d\n", sizeof(union Un1)); printf("%d\n", sizeof(union Un2)); return 0; }
输出
union实现判断
#include<stdio.h> union Un1 { int i; char c; }; int main() { union Un1 un; un.i = 1; if (un.c == 1) printf("小端"); else printf("大端"); return 0; }
输出