关于位域习题和知识整理

有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示

1)
#include <string.h>
#include <stdio.h>
#include <memory.h>
typedef struct  AA
{
        int b1:5;
        int b2:2;
}AA;
void main()
{
 AA aa;
 char cc[100];
 strcpy(cc,"0123456789abcdefghijklmnopqrstuvwxyz");
 memcpy(&aa,cc,sizeof(AA));
 printf("%d/n",aa.b1);
 printf("%d/n",aa.b2);
}
首先sizeof(AA)的大小为4,b1和b2分别占5bit和2bit.
经过strcpy和memcpy后,aa的4个字节所存放的值是:
0,1,2,3的ASC码,即00110000,00110001,00110010,00110011
所以,最后一步:显示的是这4个字节的前5位,和之后的2位
分别为:10000,和01
因为int是有正负之分  所以:答案是-16和1
2)定义一个结构体,一共有16位,变量a(0-3位),变量b(8-11位),变量c(12-15位)。
一共两种方法:
struct bs   
{   
unsigned a:4   
unsigned :0 /*空域*/   
unsigned b:4 /*从下一单元开始存放*/   
unsigned c:4   
}
struct bs   
{   
unsigned a:4   
unsigned :4 /*空出4位*/
unsigned b:4
unsigned c:4   
}
3)
#pragma   pack(1)
struct A
{
char t:4;
char k:4;
unsigned short i:8;
//unsigned short j:8;
}
sizeof(A)
把注释去掉和不去掉都是一样的,答案是3,这样可以看出虽然没有按大家一般关注的内存边界对齐(我已经设为1字节对齐了),而是按照的类型边界对齐的。
也就是说如果你定义的是short,不管用了几位它都会把剩下的位用完。
short两字节,16位,虽然没有用剩下8位,但算所占空间的时候都要算进去。
struct A
{
char t:4;
unsigned short i:8;
char k:4;
}这个列子更明显了。

#pragma   pack(4)
struct A
{
char t:4;
unsigned short i:8;
char k:4;
}结果是6
当前最大的类型是short占用2个字节
虽然是按四个字节对齐,但是仍然t占2字节,i占两字节,k占两字节
struct s1
{
  int i: 8;
  int j: 4;
  int a: 3;
  double b;
};

struct s2
{
  int i: 8;
  int j: 4;
  double b;
  int a:3;
};

printf("sizeof(s1)= %d/n", sizeof(s1));
printf("sizeof(s2)= %d/n", sizeof(s2));
16, 24
这个跟刚才的很像,只是说s1先把int占满后才开辟b;

请不要回“仔细看看”这种留言了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值