[转]c中按位分配int的方法
从网上看到这样一段c代码,让我发觉我的C基本功还是不行啊~~
- typedef struct xp {
- int a:2;
- int b:2;
- unsigned int c:1;
- } xp;
不知道大家对int声明中的这个":"熟悉吗?不过,我刚看到的时候有点懵。在网上查了些资料,才明白这是一种将int按位分配的方法。
比如:int a:2;表示a为占2位的整数。
通常的int为4字节,即占用32位的整数。
同时 按位分配的int,也分有符号和无符号两种,如:
- typedef xp
- {
- int a:2;
- unsigned int b:2;
- }MyXp;
- MyXp x;
- x.a = 3;
- x.b = 3;
这样,输出的x.a为-1,x.b为3。
同时,大家看到,这种分配方法是定义在struct中的。如果你在代码中直接定义:int a:2;编译时会导致错误,无法识别“:”。
这是因为int是内建类型,它不能被改变内存分配的方式。所以单独的int,不能直接被声明为只占2位。
而在struct中,对整个struct的内存分配,还是遵循c的内存分配方式,但在其中每一个内存位的表示含义,则可以由我们自己说明。如下:
- printf("%d/n", sizeof(x));
- printf("%d/n",sizeof(x.a));
第一句能返回4,表示MyXp是占用4个字节的,其实其中的多个int,对系统来说只是将一个int截成了不同的段来使用,整个内存分配还是按照一个int来。当然,如果总位数超过了32位,那struct大小会以4字节为单位递增,即struct的大小为4字节、8字节、12字节等。
而同时,第二句printf编译错误,是因为系统识别不出x.a的类型,因为他不是普通的int类型,系统无法识别x.a占用了2位。
从内存上看,a和b占用了x的32位中的低4位,高位没有分配的会以0值填充。
有兴趣的可以看一下运行时的内存分配。struct中的a、b是公用一个int的内存段,如果再添加新的变量,他们也是使用同一个int内存段,直到一个int段不够,则直接再开一个int段供使用。同时,如果反编译这段代码,也能发现,对a、b的赋值和访问和一般的int不同,是通过位操作来进行的。
注意,共享内存段的只能是在struct中连续声明的按位分配的int变量,如下声明:
- typedef struct xp {
- int a:3;
- int b:2;
- int k;
- unsigned int c:2;
- } xp;
则xp会占用3个int的内存段,因为a、b共享一个int的4字节,k自己单独占用一个int,c则需要开一个新的int内存段使用。而如果将k和c的声明互换,则xp只需要占用2个int的内存段。
[转]c中按位分配int的方法的更多相关文章
- [翻译] Linux 内核中的位数组和位操作
目录 Linux 内核里的数据结构 原文链接与说明 Linux 内核中的位数组和位操作 位数组声明 体系结构特定的位操作 通用位操作 链接 Linux 内核里的数据结构 原文链接与说明 https:/ ...
- 通过扩展redis-cli来实现在redis集群中移动槽位
下面的扩展代码基于redis 5.0.2进行扩展, 对于其他的redis版本, 我没有进行相关的测试.考虑到redis集群的修改频率,这段代码应该同时适用于其他的redis版本. 下面为修改的代码: ...
- Java中数据存储分配
(1)内存分配的策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编 译时就可以给 ...
- Netty 中的内存分配浅析
Netty 出发点作为一款高性能的 RPC 框架必然涉及到频繁的内存分配销毁操作,如果是在堆上分配内存空间将会触发频繁的GC,JDK 在1.4之后提供的 NIO 也已经提供了直接直接分配堆外内存空间的 ...
- Netty 中的内存分配浅析-数据容器
本篇接续前一篇继续讲 Netty 中的内存分配.上一篇 先简单做一下回顾: Netty 为了更高效的管理内存,自己实现了一套内存管理的逻辑,借鉴 jemalloc 的思想实现了一套池化内存管理的思路: ...
- [c语言]c语言中的内存分配[转]
在任何程序设计环境及语言中,内存管理都十分重要.在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的.因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题. 第1节主要介绍内存管理基本概念,重 ...
- C语言中两位ASCII码可以表示汉字
最近偶然有人问到这个相关字符编码的问题,所以百度了下参考了这两个资料,进行了简单分析. ******************************************************** ...
- C语言中的内存分配与释放
C语言中的内存分配与释放 对C语言一直都是抱着学习的态度,很多都不懂,今天突然被问道C语言的内存分配问题,说了一些自己知道的,但感觉回答的并不完善,所以才有这篇笔记,总结一下C语言中内存分配的主要内容 ...
- Java中的内存分配机制
Java的内存分为两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型变量和对象的引用都在函数的栈内存中分配.当在一个代码块中定义一个变量的时候,java就在栈中为其分配内存,当超过作用域的 ...
随机推荐
- centos7下添加开机启动
在/etc/systemd/system下创建weblogic .Service touch weblogic.Service 添加启动权限 chmod +x weblogic.Service 编辑w ...
- Python Third Day-函数
''' 为什么要有函数?没有函数带来的困扰? 组织结构不清晰,可读性差 代码冗余 可扩展性差 什么是函数 具备某一个功能的工具--->函数 事先准备工具->函数的定义 拿来就用.重复使用- ...
- js获取移动端触摸坐标
想在touchmove事件里监听手指按下的坐标,event.pageX获取的是undefined,changedTouches,targetTouches,touches也只获得到了鼠标按下时的坐标, ...
- perl学习之:subs函数
在Perl中,sub关键字主要是为了定义一个子例程,那么subs又是什么呢? 首先subs是一个函数,用于预先声明子例程,函数的参数是预声明的函数名列表.那么这个函数存在的意义是什么?首先,通过该函数 ...
- Codeforces C. Sonya and Problem Wihtout a Legend(DP)
Description Sonya was unable to think of a story for this problem, so here comes the formal descript ...
- nw335 debian sid x86-64 -- 5 使用xp的驱动
nw335 debian sid x86-64 -- 5 使用xp的驱动
- sql存储过程打印图形
print '三角形' declare @a int set @a=1 while(@a<10) begin print replace(space(@a),' ','*') set @a=@a ...
- 利用visual studio 搜索替换功能清除项目中javascript文件的debugger;
在做web项目中,写js代码时候,会有一堆的debugger;,当时又懒得删,后面就多起来了,在vs的编辑器里面,其查找替换功能支持正则和整个项目/解决方案替换,这样就很容易删掉debugger;,方 ...
- vc调试大全
一.调试基础 调试快捷键 F5: 开始调试 Shift+F5: 停止调试 F10: 调试到下一句,这里是单步跟踪 F11: 调试到下一句,跟进函数内部 Shift+F11: 从当前函数中跳 ...
- java编程思想阅读记录
第五章:初始化与清理 1.构造器确保初始化 构造器采用与类名相同的方法. 创建对象时,将会为对象分配存储空间,并调用相应的构造器.这就确保了在你能操作对象之前,它就已经恰当的被初始化了. 垃圾回收器负 ...