当前位置:网站首页>c语言位段
c语言位段
2022-08-09 07:08:00 【BSP初级小学僧】
我们在存储一些数据有时候并不需要一个完整字节,可能只需要使用几个bit位存储数据即可,所以为了节省内存空间,C语言提供“位段”的数据结构,可以把一个(或多个)字节分成几个不同位数(bit)区域,这样就可以把几个对象放到不同的区域然后用一个(或多个)字节来表示。
位段声明形式和定义结构体相似,但它的成员是一个或多个位的字段,其结构为:
struct 结构名
{
位段列表;
};
struct bit_sizeof
{
int a:2;//00 01 10 11
int b:3;
int c:8;
int d:30;
};
其中位段列表形式如下,其中位段长度指的是某个成员变量所占用的二进制位数(bit):
类型说明符 位段名:位段长度
一个位段声明的例子1:
struct CHAR
{
unsigned ch : 7;
unsigned font : 8;
unsigned len : 9;
}ch1;
上例中,每个成员变量位宽大小分别是7bit、8bit、9bit,使用sizeof()得出所占大小为4字节,因为是成员类型相同,所以后面的成员紧邻前一个成员存储,总共24bit,不满一个unsigned 类型长度,所以大小为4字节。
需要注意的是,位段的宽度不能超过它所依附的数据类型的长度,也就是说每个成员变量的类型都会有大小限制,如果“:”后面的数据超过了这个长度,运行后输出的该值可能出错,需要注意。另外,若成员的长度大于位段宽度则可能输出不完整,如下例2:
struct bs
{
unsigned char ch1 : 8;
unsigned char ch2 : 6;
//unsigned char ch3 : 9; //位段宽度超过数据类型宽度,gcc编译出错
}test;
1.当位段成员的类型相同时,位段成员会挨着存储,若存储后位段成员的bit位宽之和小于类型大小,则sizeof()该段位为类型大小,若位宽之和总大小大于类型大小,则sizeof()该段位大小为,则其偏移量为类型大小的整数倍。
该例中,位段成员位宽之和小于该类型大小,sizeof()该位段为4;
struct bs
{
int a: 1;
int b: 2;
int c: 3;
} ;
该例中,位段成员位宽之和大于该类型大小,sizeof()该位段为8
2.当相位段员的类型不同时,不同系统环境sizeof()该段位可能会有不同的大小结果。
该例中,gcc下运行sizeof()该位段大小为4,表明三个位段成员会挨着存储;在vs2010下运行sizeof()该位段大小为8,表明前两个位段成员挨着存储,后一个位段成员与前两个成员类型不同,所以另起一个单元存储。
struct bs
{
int a : 1;
int b : 4;
char c : 4;
} ;
#include <stdio.h>
void bit_size(void);
int main()
{
bit_size();
return 0;
}
void bit_size(void)
{
struct bit_sizeof
{
int a:2;//00 01 10 11
int b:3;
int c:8;
int d:30;
};
struct bit_sizeof bit_01;
bit_01.a=3;//初始化
unsigned char *p=&bit_01;//字符型指针指向bit_01的首地址
printf("*p=%#p\n",p);//地址位置
printf("*p=%u\n",*p);
bit_01.b= 0x1E;
printf("*p=%u\n",*p);
}
运行结果:
作业1: 请编写一个程序将一个整型变量右移4位,并以二进制的形式输出移位前和移位后的数值,看看你的系统是补0还是补1?
#include <stdio.h>
int main()
{
int a;
printf("请输入一个整数:\n");
scanf("%d",&a);
int c=a;
unsigned int b = 0x1<<31;
for(int i=1;i<=32;i++)
{
a & b? putchar('1') : putchar('0');
a <<= 1;
if(i%8==0)
printf(" ");
}
c >>= 4;
printf("\n");
for(int i=1;i<=32;i++)
{
c & b? putchar('1') : putchar('0');
c <<= 1;
if(i%8==0)
printf(" ");
}
return 0;
/*
请输入一个整数:
87654321
00000101 00111001 01111111 10110001
00000000 01010011 10010111 11111011
*/
}
由结果可知:本系统补0
作业2:无符号数左移移位相当于该数乘以2,编写一个函数,接收两个整型变量num和pow作为实参,被掉函数使用移位运算计算num*2\^pow的结果。然后分别以整型和二进制形式输出。
#include <stdio.h>
int main()
{
int a,b;
printf("请输入两个整数\n");
scanf("%d %d",&a,&b);
change(a,b);
return 0;
}
void change(int x,int y)
{
int z=(x<<1)^y;
printf("%d\n",z);
unsigned int b = 0x1<<31;
for(int i=1;i<=32;i++)
{
z & b? putchar('1') : putchar('0');
z <<= 1;
if(i%8==0)
printf(" ");
}
}
边栏推荐
- 高德地图JS - 已知经纬度来获取街道、城市、详细地址等信息
- AD picture PCB tutorial 20 minutes clear label shop operation process, copper network
- P6 ali machine test of 2020 Fibonacci number
- 【转载】Deep Learning(深度学习)学习笔记整理
- 找不到和chrome浏览器版本不同的chromedriver的解决方法
- Pytorch 训练技巧
- SSL证书最长有效期13个月,还有必要一次申请多年吗?
- The division principle summary within the collection
- vim 程序编辑器的基本操作(积累)
- way of thinking problem-solving skills
猜你喜欢
postgresql窗口功能
排序第一节——插入排序(直接插入排序+希尔排序)(视频讲解26分钟)
Tkinter可以选择的颜色
分布式事务产生的原因
Altium designer software commonly used the most complete package library, including schematic library, PCB library and 3D model library
常见的分布式事务解决方案
Use tensorflow.keras to build a neural network model modularly
高项 03 项目立项管理
【Oracle 11g】Redhat 6.5 安装 Oracle11g
The JVM thread state
随机推荐
Important news丨.NET Core 3.1 will end support on December 13 this year
力扣第 305 场周赛复盘
字节也开始缩招了...
Lottie系列三 :原理分析
Quectel EC20 4G module dial related
如何 认识与学习BASH
【模板】树链剖分 P3384
dp学习笔记
搭载开源鸿蒙系统的嵌入式XM-RK3568工业互联方案
常用测试用例设计方法之正交实验法详解
RK3568商显版开源鸿蒙板卡产品解决方案
高项 01 信息化与信息系统
postgresql Window Functions
类和结构体
car-price-deeplearning-0411
TCP段重组PDU
Forest Program dfs+tanjar仙人掌
SSL证书最长有效期13个月,还有必要一次申请多年吗?
浅识微服务架构
找不到和chrome浏览器版本不同的chromedriver的解决方法