浅谈 位段?枚举?联合?

一、位段
位段是C语言中用于在一个结构体(或联合体)内以位为单位来指定其成员所占的内存长度。在计算机存储中,一个字节是由8个位组成的,有些时候定义变量采用位段的形式,可以有效地节省空间,但是位段存在跨平台的问题,不同的机器位,其使用也有不同。
定义一个位段结构体的方法和定义结构体是类似的,区别在于:
a)位段的类型只能是int、unsigned int、signed int或char类型;
b)位段的成员名后必须是‘:’加上数字,就像下面这样:
unsigned int you:6 //变量you的类型是unsigned int,占6位
接下来是使用位段时应注意的问题:
1.位段成员的长度不能大于该成员类型的存储长度,比如int在VC中是4个字节,即32位,则int类型的位段成员二进制位数不能超过32位;
2.不能定义位段数组,不能对位段成员进行取地址操作;
3.可以出现无名位段,如:
int :0;//该变量占0位
无名位段不能被访问,但也会占据空间;
4.一个位段必须存储在同一存储单元中,不能跨两个单元。如果第一个单元空间不能容纳下一个位段,则该空间不用,从下一个单元起存放该位段;
5.若出现了无名位段,则下一位段就必须得从下一位段存储单元开始存放,比如:

struct sport{
int football:13;
int basketball:9;//一个存储单元
unsigned int:0;//无名位段
signed int running:4;//另一个存储单元
};

6.如果一个位段结构中只有一个占有0位的无名位段,则只占1或0字节的空间(C语言中是占0字节,而C++中占1字节),其他任何情况下,一个位段结构所占的空间至少是一个位段存储单元的大小;
7.位段出现在表达式中,会被系统自动转为int或unsigned int类型;
8.位段输出用整形格式符输出;
9.位段结构定义的第一个成员不能所占位数不能为0;
如何计算位段结构的大小呢???

struct A {     
int a:2;     
int b:5;     
int c:10;     
int d:30; 
};
int main()
{
    int m = sizeof(struct A);
    printf("%d", m);
}
//结果m=8;

上面的例子可知道,a,b,c分别占2位、5位、10位,共17位<32位(VC下一个位段存储单元是4字节),d占30位,无法继续与a,b,c放在同一位段存储单元中,所以要放在另一单元,则结构体的大小是8;

struct node{ 
    signed int a:3; //只存在一个非0位的位段,至少占4字节 
}S; 

struct node1 
{ unsigned int :0;//在C++中占1字节的空间 ,在C中占0字节
}S1;
struct node2{ 
    unsigned int a:1;
    unsigned int :0; //出现无名位段,则下一位段放在一个新的位段存储单元 
    unsigned c:32;
}S2;//4+4=8字节

struct node3{ 
    unsigned int a:4;
    unsigned int :0; //一个位段存储单元
    int :8; //这个位段放在一个新的位段存储单元 
    unsigned c:32; //因为12+32>32,位段c也放在一个新的位段存储单元
}S3;//4+4+4=12Byte

struct node4 {
    unsigned int a:1;
    char b; 
    int c:1; 
    int d:2;
    unsigned int e:2;
}S4;//在一个位段存储单元中能够存下所有的成员,所以占4字节

二、枚举
枚举是一个整型常数的集合,它的定义格式如下:
enum 枚举名{
标识符=整型常数,
…=整型常数,
…=整型常数,
………..,
…=整型常数,
}枚举变量名;
其中“ =整型常数”是可以省略的,若不写明的话,则集合内部成员的常数值从0开始依次递增1;最后一个成员可省略“,”;枚举变量的大小实质是常数类型的大小,所以为4字节;
我使用枚举变量的好处是:使用很方便,代码可读性高,不会混乱,同时也更加严谨。

enum Day {     
Mon,     
Tues,     
Wed,     
Thur,     
Fri,     
Sat,     
Sun }day;
enum Day {     
Mon=1,     
Tues=2,     
Wed=3,     
Thur=4,     
Fri
};

三、联合体
几个不同的变量共同占用同一段内存的结构称为“联合体”类型,联合体的定义和结构体相似:
union 联合体名{
类型说明符 成员名;
}联合体变量名;
联合变量可被赋予任一成员值,但每次只能赋一种值,赋入新值则冲去旧值,也就是说联合体中起作用的成员是最后一次放进去的成员;
联合体结构的地址和它的成员地址是一样的;
可对联合体成员进行赋值,访问其成员可以运用’.‘操作符,每次对一个成员赋值后,之前的赋值成员就会失去作用,可理解为它们之间是互斥的;
联合类型的定义和联合变量的说明一个联合类型必须经过定义之后,才能把变量说明为该联合类型。
联合体的大小:
联合的大小至少是最大成员的大小,当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
如:

union U{ 
char s[9]; //9字节
int n;//4字节
double d;// 8字节 
};

成员最大大小是9字节,但最大对齐数是8,所以联合体实际大小是16.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值