C语言位域解析&符号位扩展规则
从一个例子说起:
int main(void){
union{
int i;
struct{
char a : ;
char b : ;
char c : ;
}bits;
}num;
printf("Input an integer for i(0~15): ");
scanf("%d", &num.i);
printf("i = %d, cba = %d %d %d\n", num.i, num.bits.c, num.bits.b, num.bits.a);
return ;
}
输入i值为11,则输出为i = , cba = - - -。 为什么?
,位域的定义
在结构体的定义中,指定元素所占用的bit数, 并指定类型。 按照结构体的成员调用方式进行调用。
,位域的内存对应规则
一个字节按照从高位到低位 bit7 ~ bit0,对于位域的定义,是从低位bit0 开始算起的(注意不是从高位开始对应)。也就是说,上面例子中的位域,在一个字节中对应的存储是 ccba, a在最低位,然后是b,和占两个bit的c。 c成员中按照bit3高位、bit2低位存储。
,大小端问题
对于小端来说,低字节存放在低地址中,int的存储从0x00地址到0x03地址,依次是 。
联合体从头开始,是对内存中数据的截断和强转, 根据刚才位域的存储结构,cc的截断是10, b和a的截断都是1。
,为什么打印出来是负数? ---》补码的规则
在计算机的内存中,所有的数据存储都是按照补码存储的。 对于有符号数来说,正数的补码是正数自身,负数的补码是反码+。这都没问题。
问题的核心还是符号位。计算机里从低精度数向高精度数转换时,比如从char到short, 又比如这里从10两个bit填充为一个char的8个bit, 肯定会在前面扩展一些bit位,从而达到高精度数的长度。那么扩展时,是补0还是补1呢?这里有个原则就是,有符号数扩展符号位,无符号数扩展0。对应到这里也就是1。注意,这里说的是有符号数和无符号数,对于有符号的正数,因为符号位是0,所以也是补零。然而我们在位域的定义中,定义了abc都是有符号的char型。所以在向8位扩展时,因为第一位都是1,所以往前都扩展1,a和b在内存中为11111111, c为11111110,都是补码。按照%d打印出来以后, 就是- 和 -。 如果这里定义成 unsigned char,按照定义前面补0,打印结果就会是正数了。
C语言位域解析&符号位扩展规则的更多相关文章
- Java中符号位扩展
第一个例子: byte b=-100;b在内存中是以补码的形式存贮的:1001 1100 如果执行char c=(char)b;如3楼企鹅先生所说:b要先变为int,这时增加的位全要用b的符号位填充( ...
- 浅谈Java中的补零扩展和补符号位扩展
今天,魏屌出了一道题,题目如下: 定义一个大头序的byte[]a={-1,-2,-3,-4},转换成short[]b.问b[0]和b[1]分别是多少? 乍一看,这题不难,无非就是移位操作,再进行组合. ...
- C++ 中注意,零扩展和符号位扩展
版权声明:本文为博主原创文章,未经博主允许不得转载. 首先,介绍一下两种扩展的定义 转 http://blog.csdn.net/jaylong35/article/details/6160736 符 ...
- Java 移位运算、符号位扩展
类型取值范围 short 是1字节,即8位.而且 Java 中只有有符号数,所以最大值 0111,1111=2^7-1. 同时计算机中以补码形式存负数,所以可以多表示一个数,则最小值 1000,000 ...
- 深入理解计算机系统(2.4)---C语言的有符号与无符号、二进制整数的扩展与截断
开篇请各位猿友允许LZ啰嗦几句,最近一直在写计算机系统原理这系列文章,也已经下定决心要把这本书的内容写完.主要目的其实是为了巩固LZ的理解,另外也想把这些内容分享给猿友们,毕竟LZ觉得这些内容对程序猿 ...
- verilog中符号位的扩展问题
以下内容转自 艾米电子 - 使用有符号数,Verilog(http://www.cnblogs.com/yuphone/archive/2010/12/12/1903647.html) Verilog ...
- C语言的有符号与无符号,二进制整数的扩展与截断
C语言的有符号与无符号,二进制整数的扩展与截断 前一节说了整数的表示方式,,也就是无符号编码与补码编码.这一届说一下二进制整数的扩展与截断,这部分内容与C语言挂钩.so,我们先看下面C语言的有符号和无 ...
- C语言位域精解(转)
有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态,用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一种数据结构, ...
- C语言位域
转载自 http://tonybai.com/2013/05/21/talk-about-bitfield-in-c-again/ 再谈C语言位域 五 21 bigwhite技术志 bitfield, ...
随机推荐
- 软件包管理:源码包管理-源码包与RPM包的区别
RPM会安装在默认位置,源码包会安装在指定位置. 绝大多数ROM包遵循此规范.写软件包是就固定好了. 主要影响体现在对服务的管理方法,服务的管理分三种:启动,重启动,停止. 启动时使用绝对路径来启动. ...
- Javascript--普通函数调用-涨工资计算函数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Centos下添加PHP对MSSQL的支持
Leave a reply 其实很少会有连接SQL Server的机会,不过我们公司刚好有个应用需要使用的SQL Server的数据库,所以也知道给LNMP安装MSSQL的扩展. 搜索网上的相关文章一 ...
- 通俗理解RxJS(一)
自学 Rx 快有一个周了, 它非常适合处理复杂的异步场景.结合自己所学,决定写系列教程. 我认为, Rx 中强大的地方在于两处 管道思想,通过管道,我们订阅了数据的来源,并在数据源更新时响应 . 强大 ...
- STA分析(二) multi_cycle and false
multicycle path:当FF之间的组合逻辑path propagate delay大于一个时钟cycle时,这条combinational path能被称为multicycle path. ...
- mac远程连接windows
第一步:在Mac上安装Remote Desktop Connection 进入Microsoft Remote Desktop Connection下载安装包. 下载完成之后,双击安装包进行安装. 第 ...
- MacaW Baby Learns Computer
A - Macaw Baby Learns Computer Time Limit:1000MS Memory Limit:0KB 64bit IO Format:%lld & ...
- MySQL从删库到跑路_高级(四)——存储过程
作者:天山老妖S 链接:http://blog.51cto.com/9291927 一.存储过程简介 1.存储过程简介 存储过程是一组具有特定功能的SQl语句集组成的可编程的函数,经编译创建并保存在数 ...
- Ignite缓存大小管理
Ignite使用计算机内存存储缓存数据,达到提升缓存读写性能的.但是计算机内存往往是有限的,我们必须合理管理Ignite对内存的使用. Ignite可以使用JVM堆外内存和堆内内存.使用堆外内存基本上 ...
- nodejs中req.body对请求参数的解析问题
首先,先了解一下关于http协议里定义的四种常见数据的post方法,分别是: application/www-form-ulrencoded multipart/form-data applicati ...