c中位段的使用

网易 广州 梦幻西游端游 客户端社招笔试题 2024 4道算法题,时间2小时,牛客网笔试注:采用OJ模式,需要自己处理输入、输出。 阅读详情
/*
        DATE : 2010.6.24
        关于C中的位端igned或者int
*/
#include <stdio.h>

typedef struct _A
{
        unsigned a:4;//位段成员的类型仅能够为unsigned或者int
        unsigned b:4;
        unsigned c:2;
        unsigned d:6;
        unsigned E:1;
        unsigned D:2;
        unsigned T:3;
        unsigned A:9;
        unsigned h:4; //前面已经为31,故4+31>32已超过一个存储单元,所以4在一个新的存储单元存放
        unsigned y:29;//由于前面的4在一个新的存储单元的开头存放,且29+4>32, 故在另一个新的存储单元存放
}A;               //所以最后求出的A的大小是4 + 4 + 4 =12

/*对上面的具体解释: 一个位段必须存储在同一个存储单元中,不能跨两个单元.如果某存储单元空间中不能容纳
                                    下一个位段,则改空间不用,而从下一个存储单元起存放该位段. 结构体A中的h和y就是这种情况.
                                        在gcc环境下,测试后,一个存储单元为4个字节.
*/

typedef struct _S
{
        unsigned a:4;
        unsigned b:4;
        unsigned c:22;
        unsigned q:1;
        unsigned h:1;
        //unsigned i:33;  // 错误:‘i’ 的宽度超过它自身的类型
        //unsigned i:1;当多出此行时,该结构体大小由4变为8,因为此行之前正好为32位
} S;

typedef struct _T
{       //当没有占满一个存储单元时,结构体的大小对齐为一个存储单元的大小
        unsigned a:2;
        unsigned b:2;
        unsigned j:1;
        unsigned : 1;//可以定义无名位段,此例中该无名位段占用1位的空间,该空间将不被使用
} T;

typedef struct _V
{
        unsigned a:1;
        unsigned b:4;
        unsigned :0;    //定义长度为0的位段时不能指定名字,否则编译不过
        unsigned d:1;   //定义了0字段后,紧接着的下一个成员从下一个存储单元开始存放;
}V;                                     //此例子中,d前面那个存储单元中的余下的27位中被0填充了


int main()
{
        A a; S s; T t; V v;
        printf("sizeof(a)=%d\n", sizeof(a));
        printf("sizeof(s)=%u\nsizeof(t)=%u\n", sizeof(s), sizeof(t));
        printf("sizeof(v)=%d\n", sizeof(v));
        return 0;
}





摘自http://fayaa.com/code/view/11795/   作者: glq2000





位段(bit-field)是以位为单位来定义结构体(或联合体)中的成员变量所占的空间。

含有位段的结构体(联合体)称为位段结构。采用位段结构既能够节省空间,又方便于操作。


     位段的定义格式为:


     type  [var]: digits


    其中type只能为int,unsigned int,signed int三种类型(int型能不能表示负数视编译器而定,比如VC中int就默认是signed int,能够表示负数)。位段名称var是可选参数,即可以省略。digits表示该位段所占的二进制位数。


   那么定义一个位段结构可以像下面这段代码去定义:

struct node
{
    unsigned int a:4;     //位段a,占4位
    unsigned int  :0;     //无名位段,占0位
    unsigned int b:4;     //位段b,占4位
    int c:32;             //位段c,占32位
    int  :6;              //无名位段,占6位
};


一.位段的使用


    使用位段需注意一下几点:


    1)位段的类型只能是int,unsigned int,signed int三种类型,不能是char型或者浮点型;


    2)位段占的二进制位数不能超过该基本类型所能表示的最大位数,比如在VC中int是占4个字节,那么最多只能是32位;


    3)无名位段不能被访问,但是会占据空间;


    4)不能对位段进行取地址操作;


    5)若位段占的二进制位数为0,则这个位段必须是无名位段,下一个位段从下一个位段存储单元(这里的位段存储单元经测试在VC环境下是4个字节)开始存放;


    6)若位段出现在表达式中,则会自动进行整型升级,自动转换为int型或者unsigned int。


    7)对位段赋值时,最好不要超过位段所能表示的最大范围,否则可能会造成意想不到的结果。


    8)位段不能出现数组的形式。


二.位段结构在内存中的存储方式


    对于位段结构,编译器会自动进行存储空间的优化,主要有这几条原则:


   1)如果一个位段存储单元能够存储得下位段结构中的所有成员,那么位段结构中的所有成员只能放在一个位段存储单元中,不能放在两个位段存储单元中;如果一个位段存储单元不能容纳下位段结构中的所有成员,那么从剩余的位段从下一个位段存储单元开始存放。(在VC中位段存储单元的大小是4字节).


   2)如果一个位段结构中只有一个占有0位的无名位段,则只占1或0字节的空间(C语言中是占0字节,而C++中占1字节);否则其他任何情况下,一个位段结构所占的空间至少是一个位段存储单元的大小;


  测试程序:

/*测试位段 201110.12*/ 
#include<iostream>
using namespace std; 

typedef struct node
{
    unsigned int a:1;      //存在一个非0位的位段,则至少占4Byte 
}S; 

typedef struct node1       //在C++中占1字节的空间 ,在C中占0字节 
{
    unsigned int :0;
}S1;

typedef struct node2
{
    unsigned int a:1;
    unsigned int  :0;     //下一个位段放在一个新的位段存储单元 ,所以占4+4=8Byte 
    unsigned c:32;         
}S2;

typedef struct node3
{
    unsigned int a:4;
    unsigned int  :0;
    int :6;               //这个位段放在一个新的位段存储单元 
    unsigned c:32;        //由于6+32>32,所位段c也放在一个新的位段存储单元,所以占4+4+4=12Byte 
}S3;

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


int main(int argc, char *argv[])
{
    S4 s4;
    s4.a=1;
    s4.c=1;
    s4.d=2;              
    s4.e=3;
    printf("%d %d %d %d\n",s4.a,s4.c,s4.d,s4.e);
    printf("%d %d %d %d %d\n",sizeof(S),sizeof(S1),sizeof(S2),sizeof(S3),sizeof(S4));
    return 0;
}


执行结果为:


1 -1 -2 3
4 1 8 12 4
请按任意键继续. . .
当打印s4的各个位段时,打印的结果与赋的初始值不同。


由于c只占1位,那么没有数据位,此时进行符号扩展直接在高位添加1,所以打印的结果为-1;


由于d占2位,那么当将2赋给d时,内存中存储的内容为10,此时进行符号扩展,高位补1,则为0XFF FF FF FE,那么其真值则为-2.



摘自http://www.cnblogs.com/dolphin0520/  作者:海子


电流镜设计实战:从基础到高级技巧(附常见问题解决方案) 本文从工程实战角度,系统讲解了电流镜设计从基础原理到高级技巧的全过程。深入剖析了匹配精度、输出阻抗等核心矛盾,并详细介绍了共源共栅(Cascode)结构如何平衡电压裕度与输出阻抗。文章还重点探讨了工艺偏差、版图应力效应等实战中的“隐形杀手”,并提供了常见问题的解决方案与调试技巧,旨在帮助工程师设计出鲁棒性更强的模拟电路。 阅读详情

相关推荐

STM32--基于STM32F103C8T6的OV7670摄像头显示

使用 STM32F103C8T6 微控制器驱动 OV7670 摄像头模组,并将图像数据显示在屏幕上,是嵌入式系统中常见的图像采集与显示应用。OV7670 是一款 CMOS VGA 图像传感器,具有高灵敏度、低电压等特点,适用于嵌入式应用。而 STM32F103C8T6 是一款常用的 MCU 控制器,具有丰富的管脚资源和较高的工作频率。

duierrorshuobu的博客 2145

C语言之位段(详解)

C语言中位段的详细介绍(内存分配 跨平台问题 应用 赋值)

林林林的博客 1990

智能化运维(AIOps)

• 调查显示,54.79%的企业当前着重关注智能运维的质量领域(包括异常检测、告警收敛、根因分析、 故障处置等)能力建设,其次45.77%的企业关注效率领域,45.49%的企业关注成本领域,30.82%的 企业关注安全领域。从目前的发展情况来看,现阶段AIOps能力大多集中在L2级别, 主要以系统辅助分析,帮助人工进行决策和操作为主,较为领先的 能力实践可以达到L3级别,而L4和L5级别随着AIOps的技术发展 和能力的逐步增强,将是未来智能运维能力建设的发展方向和目标。

追求更专业的设计 3097

【详解】C语言冷门知识点之--位段

位段(或称“位域”,Bit field)为一种数据结构,可以把数据以位的大家有没有发现,我们在声明位段的时候,如果定义的是int,那么冒号后面跟上的数字不能超过32,如果定义的是char,那么冒号后面跟上的数字不能超过8。而位域这种数据结构的缺点在于,其内存分配与内存对齐的实现方式依赖于具体的机器和系统,在不同的平台可能有不同的结果,这导致了位段在本质上是不可移植的。以上也证明了, 在VS2022上,位段分配的内存中的比特位是从右向左使用的,分配剩余的比特位不够使用时,浪费掉剩余内存,重新开辟新的空间。

tang20030306的博客 3704

usb设备的定位信息获取

一个usb hub有20个口,每个口有一个标号,那么如果一个为X的标号插入了一个android设备,如何通过函数,得到这个X,代码实现如下,获取了location, 得到类似 Port_#0002.Hub_#0003 的字符串,然后,要对应一个表。

babytiger的专栏 2106

FPGA驱动OV5640:从SCCB协议到图像数据采集的实战解析

本文详细解析了使用FPGA驱动OV5640摄像头模组的完整流程,从SCCB协议通信、寄存器配置到图像数据采集。重点阐述了SCCB(与I2C类似)协议的实现细节、关键的上电复位时序,以及如何通过状态机解析视频流时序并捕获图像数据,为嵌入式视觉开发提供了实战指南。

weixin_29191761的博客 187

C语言位段详解

例如,如果我们定义了一个 unsigned int 类型的位段,宽度为3位,那么它实际上会占用一个字节的空间(8位),因为 unsigned int 类型在大多数机器上是4个字节(32位)。在这个例子中,我们定义了一个结构体变量 bitField,其中包含三个位段成员,分别是a、b、c,它们的宽度分别为1位、2位、3位。其中,a、b、c、d 分别占用 1、2、3、4 个位,共计 10 个位,但是由于内存对齐的原因,它实际上占用了两个字节的空间。除了定义单个位段之外,我们还可以定义包含多个位段的结构体。

qq_41954181的博客 538

Arduino MLX90393磁力计驱动库:高精度三轴霍尔传感器开发指南

三轴霍尔效应磁力计是嵌入式系统中实现无接触角度检测、电子罗盘与电流传感的核心器件。其工作原理基于霍尔电压随外磁场矢量变化的物理特性,通过I²C接口输出高分辨率(16/20-bit)XYZ轴原始数据,并集成温度补偿与数字滤波功能。技术价值体现在确定性响应、低功耗(典型0.5 μA待机)及强抗干扰能力,适用于电池供电设备与实时操作系统环境。典型应用场景包括电机位置反馈、永磁体旋转角度解算、工业编码器和地磁导航。本库专为Arduino生态优化,深度封装MLX90393寄存器协议与自校准流程,同时兼容STM32、E

weixin_29363791的博客 641

C语言-位段详解

C语言之结构体位段

局部变量和全局变量 2561

旗鱼优化算法(SFO)详解:从海洋猎手到智能优化

旗鱼优化算法(SFO)是一种新型群体智能优化算法,灵感来源于旗鱼的群体捕食行为。该算法采用双种群机制,模拟旗鱼(精英个体)与沙丁鱼(普通个体)的交互过程,通过交替攻击策略实现探索与开发的平衡。核心机制包括:基于猎物密度的旗鱼位置更新、随迭代衰减的攻击力度控制、以及捕食替换机制。SFO具有参数少、全局搜索能力强等特点,在高维复杂优化问题中表现优异。算法通过模拟自然界中的群体智能行为,为解决工程优化问题提供了新思路。

qq_42212808的博客 163

YOLOv8-Pose NCNN Android部署优化实践

本文探讨了在Android设备上高效部署YOLOv8-Pose姿态检测模型的优化实践。通过修改Pose头部导出逻辑,分离后处理到C++端实现,并替换SiLU激活函数为ReLU,显著提升了计算效率。具体步骤包括模型结构优化、ONNX导出、NCNN转换与算子融合,最终在Android端实现了30FPS的稳定推理性能。项目提供了完整的优化思路和实现方案,对移动端AI应用开发具有参考价值。

FJN110的博客 323

C语言-位段

1、什么是位段 C语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为位段。利用位段能够用较少的位数存储数据。 2、位段在使用中需要注意的一些点: 1、位段的内存分配2)位段占的二进制位数不能超过该基本类型所能表示的最大位数,即位段不能跨字节存储,比如在VC中int是占4个字节,那么最多只能是32位; 1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型。 2. 位段的空间上是按照需要以4个字节( in

weixin_45897952的博客 4135

【PostgreSQL教程】PostgreSQL 高级篇之子查询

子查询也可称为内部查询、嵌套查询,指的是在 PostgreSQL 查询中的 WHERE 子句中嵌入查询语句。一个 SELECT 语句的查询结果能够作为另一个语句的输入值。子查询可以与 SELECT、INSERT、UPDATE 和 DELETE 语句一起使用,并可使用运算符如 =、、>=、

No8g攻城狮的博客 1206

浅谈C语言位段

记录C语言小白的学习历程 C语言位段

2402_86037826的博客 2997

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【C语言】位段(结构体实现位段)

位段的定义,声明,内存分配,在内存中的存储方式,位段的优点,位段的跨平台问题,位段的应用,位段使用的注意事项

2301_79633555的博客 2128

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

c语言位段的作用,c语言中位段的使用

含有位段的结构体类型称为位段结构。位段结构也是一种结构体类型,只不过其中含有以位为单位定义存储长度的整数类型位段成员。采用位段结构既节省存储空间,又可方便操作。位段结构中位段的定义格式为:unsigned :例如:struct bytedata{unsigned a:2; /*位段a,占2位*/unsigned:6; /*无名位段,占6位,但不能访问*/unsigned:0; /*无...

weixin_35182280的博客 607

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

重生之我在异世界学编程之C语言:深入位段篇

C语言还提供了一种特殊的结构体成员——位段(bit fields),它允许程序员精确控制结构体成员的存储大小,通常用于打包数据以节省空间或匹配硬件接口。本文将详细介绍C语言中位段的使用、大小计算以及相关的经典习题。有需要的包子可以看看!!!

z15879084549的博客 2339

c语言-位段

本篇文章介绍c语言的位段。

pyc68的博客 1674

C语言位段概念介绍

0x00 前言 文章中的文字可能存在语法错误以及标点错误,请谅解; 如果在文章中发现代码错误或其它问题请告知,感谢! 0x01概念 我们在存储一些数据有时候并不需要一个完整字节,可能只需要使用几个bit位存储数据即可,所以为了节省内存空间,C语言提供“位段”的数据结构,可以把一个(或多个)字节分成几个不同位数(bit)区域,这样就可以把几个对象放到不同的区域然后用一个(或多个)字节来表示。 位段声...

C/C++攻城狮 1168

C语言位段

有时,存储1个信息不必占用1个字节,只需二进制的1个(或多个)位就够用。如果仍然使用结构类型,则造成内存空间的浪费。 为此,C语言引入了位段类型。 位段的概念与定义 所谓位段类型, 是一种特殊的结构类型,其所有成员均以二进制位为单位定义长度,并称成员为位段。 例如,CPU的状态寄存器,按位段类型定义如下: struct status { unsigned sign:1;/*...

QQ2558030393的博客 532

C语言——位段

位段知识点大全

2403_89485883的博客 962

c语言中位段的使用

位段以位为单位定义结构体(或共用体)中成员所占存储空间的长度。     含有位段的结构体类型称为位段结构。     位段结构也是一种结构体类型,只不过其中含有以位为单位定义存储长度的整数类型位段成员。采用位段结构既节省存储空间,又可方便操作。     位段结构中位段的定义格式为:     unsigned :     例如:     struct bytedata     {unsi

家里蹲博客 885

C语言 位段

位段,C语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为“位段”或称“位域”( bit field)。利用位段能够用较少的位数存储数据。来自:百度百科-位段。

m0_64238771的博客 513

什么是位段【C语言】

1248

【C语言】位段详解

例如,即使你的位段结构体只占用了8位(即1字节),由于内存对齐的要求,实际的结构体大小可能仍然是4字节。例如,如果一个位字段在32位边界结束,而下一个位字段需要从新的32位边界开始,则编译器可能会在它们之间插入未使用的位。当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。假设:位段分配的内存中的比特位是从右向左使用的,分配剩余的bit位不够使用时,浪费掉剩余内存。位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

编程知识点梳理、项目经验总结、学习方法分享 1825

浅谈C语言中的位段

浅谈C语言中的位段       位段(bit-field)是以位为单位来定义结构体(或联合体)中的成员变量所占的空间。含有位段的结构体(联合体)称为位段结构。采用位段结构既能够节省空间,又方便于操作。      位段的定义格式为:      type  [var]: digits     其中type只能为int,unsigned int,signed int三种类型(int型能不能表示负数

zhanglp的专栏 903
上一篇: java中怎样调用抽象类中的非抽象方法?(对原文做修改,加入一点自己理解)
下一篇: Java中抽象类和接口的区别(来源一)
outer_star
博客等级 码龄14年 8粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值