位域的使用与一般的结构体使用没有多大区别,位域可以位运算
例子:1
#include <stdio.h>
typedef struct bt
{
char a:5;
char b:5;
char c:5;
char d:5;
char e:5;
}bt;
main()
{
printf("%d/n", sizeof(bt));
}
结果:
5
例子2
#include <stdio.h>
typedef struct bt
{
int a:5;
int b:5;
int c:5;
int d:5;
int e:5;
}bt;
main()
{
printf("%d/n", sizeof(bt));
}
结果:
4
例子3:
#include <stdio.h>
typedef struct bt
{
int a:5;
int b:5;
int c:5;
int d:5;
int e:5;
int f:5;
int h:5;
}bt;
main()
{
printf("%d/n", sizeof(bt));
}
结果:
8
一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始-------------------这个说法只适用于char类型的数据
当数据类型不是char时,即大于1字节时。上面的那句话应改为:一个位域必须存储在同种数据类型所占的字节中,不能跨两个同种数据类型所占的字节数。(所以第二个的结果为4,第三个结果为8)
第二个例子没有超过 int 的一个类型占用的大小,所以并不会出现那种位域跨空间存放。所以为4。
又可这样说:
使用位域的主要目的是压缩存储,其大致规则为:
1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍
(1)可以有意使某位域从下一单元开始
struct bs
{
unsigned a:4
unsigned :0 /*空域*/
unsigned b:4 /*从下一单元开始存放*/
unsigned c:4
}aa;
a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位
(2)位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的
struct k
{
int a:1
int :2 /*该2位不能使用*/
int b:3
int c:2
}bb;
从以上分析可以看出,位域在本质上就是一种结构类型,不过其成员是按二进位分配的。
#include <stdio.h>
struct bts{
char a:5;
char b:5;
char c:5;
char d:5;
char e:5;
char f:5;
char h:5;
int g:5;
}aa;
struct bt{
int gu:2;
int wan:5;
int guw:7;
int hh:7;
int hi:7;
}bb;
struct gukk{
int hhh:5;
}w;
struct hhuu{
int jj:4;
char kkl:4; // 从下一个字节存储
};
struct hhuuc{
int jj:5;
char kkl:5;
};
struct kkk{
int gu:7;
int gg:7;
int kkl:7;
char ii:4; //从下一个字节开始存储,不过都按照最长的计算 即4个字节计算 所以为8
char oo:7;
};
main()
{
printf("%d/n", sizeof(struct bts));
printf("%d/n", sizeof(struct bt));
printf("%d/n", sizeof(struct gukk));
printf("%d/n", sizeof(struct hhuu));
printf("%d/n", sizeof(struct hhuuc));
printf("%d/n", sizeof(struct kkk));
}
结果:
8
4
4
4
4
8
例子:
#include <stdio.h>
struct bt{
int a:3;
int b:3;
int d:1;
unsigned e:3; //最好写成无符号数
}aa,*bb;
main()
{
aa.a = 3;
aa.b = 7;
aa.e = 7;
printf("%d/n%d/n%d/n", aa.a, aa.b, aa.e);
bb = &aa;
bb->a |= 1;
printf("%d/n%d/n%d/n%d/n", bb->a, bb->b, bb->a, bb->e);
}
结果:
3
-1 //为有符号数
7
3
-1
3
7
几个习题: