当前位置:网站首页>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(" ");
}
}
边栏推荐
猜你喜欢
unity第一课
SAP ALV data export many of the bugs
RK3568商显版开源鸿蒙板卡产品解决方案
【报错】Root Cause com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
XILINX K7 FPGA+RK3399 PCIE驱动调试
虚拟机网卡报错:Bringing up interface eth0: Error: No suitable device found: no device found for connection
数据库索引原理
无重复的字符的最长子串
用tensorflow.keras模块化搭建神经网络模型
Distributed id generator implementation
随机推荐
如何 认识与学习BASH
2017.10.26模拟 b energy
ByteDance Interview Questions: Mirror Binary Tree 2020
list and string conversion
细谈VR全景:数字营销时代的宠儿
Important news丨.NET Core 3.1 will end support on December 13 this year
浅识微服务架构
错误:为 repo ‘oracle_linux_repo‘ 下载元数据失败 : Cannot download repomd.xml: Cannot download repodata/repomd.
mysql summary
HDU - 3183 A Magic Lamp Segment Tree
基于布朗运动的文本生成方法-LANGUAGE MODELING VIA STOCHASTIC PROCESSES
2022年7月小结
Change Jupyter Notebook default open directory
The Integer thread safe
postgresql窗口功能
Singleton DCL (double check the lock) full han mode and the hungry
MongDb query method
Distributed id generator implementation
训练好的深度学习模型,多种部署方式
Invoker 2019CCPC秦皇岛站I题 简单DP