从网上看到这样一段c代码,让我发觉我的C基本功还是不行啊~~

  1. typedef struct xp {
  2. int a:2;
  3. int b:2;
  4. unsigned int c:1;
  5. } xp;

不知道大家对int声明中的这个":"熟悉吗?不过,我刚看到的时候有点懵。在网上查了些资料,才明白这是一种将int按位分配的方法。

比如:int a:2;表示a为占2位的整数。

通常的int为4字节,即占用32位的整数。

同时 按位分配的int,也分有符号和无符号两种,如:

  1. typedef xp
  2. {
  3. int a:2;
  4. unsigned int b:2;
  5. }MyXp;
  6. MyXp x;
  7. x.a = 3;
  8. x.b = 3;

这样,输出的x.a为-1,x.b为3。

同时,大家看到,这种分配方法是定义在struct中的。如果你在代码中直接定义:int a:2;编译时会导致错误,无法识别“:”。

这是因为int是内建类型,它不能被改变内存分配的方式。所以单独的int,不能直接被声明为只占2位。

而在struct中,对整个struct的内存分配,还是遵循c的内存分配方式,但在其中每一个内存位的表示含义,则可以由我们自己说明。如下:

  1. printf("%d/n", sizeof(x));
  2. 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变量,如下声明:

  1. typedef struct xp {
  2. int a:3;
  3. int b:2;
  4. int k;
  5. unsigned int c:2;
  6. } xp;

则xp会占用3个int的内存段,因为a、b共享一个int的4字节,k自己单独占用一个int,c则需要开一个新的int内存段使用。而如果将k和c的声明互换,则xp只需要占用2个int的内存段。

[转]c中按位分配int的方法的更多相关文章

  1. [翻译] Linux 内核中的位数组和位操作

    目录 Linux 内核里的数据结构 原文链接与说明 Linux 内核中的位数组和位操作 位数组声明 体系结构特定的位操作 通用位操作 链接 Linux 内核里的数据结构 原文链接与说明 https:/ ...

  2. 通过扩展redis-cli来实现在redis集群中移动槽位

    下面的扩展代码基于redis 5.0.2进行扩展, 对于其他的redis版本, 我没有进行相关的测试.考虑到redis集群的修改频率,这段代码应该同时适用于其他的redis版本. 下面为修改的代码: ...

  3. Java中数据存储分配

    (1)内存分配的策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编 译时就可以给 ...

  4. Netty 中的内存分配浅析

    Netty 出发点作为一款高性能的 RPC 框架必然涉及到频繁的内存分配销毁操作,如果是在堆上分配内存空间将会触发频繁的GC,JDK 在1.4之后提供的 NIO 也已经提供了直接直接分配堆外内存空间的 ...

  5. Netty 中的内存分配浅析-数据容器

    本篇接续前一篇继续讲 Netty 中的内存分配.上一篇 先简单做一下回顾: Netty 为了更高效的管理内存,自己实现了一套内存管理的逻辑,借鉴 jemalloc 的思想实现了一套池化内存管理的思路: ...

  6. [c语言]c语言中的内存分配[转]

    在任何程序设计环境及语言中,内存管理都十分重要.在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的.因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题. 第1节主要介绍内存管理基本概念,重 ...

  7. C语言中两位ASCII码可以表示汉字

    最近偶然有人问到这个相关字符编码的问题,所以百度了下参考了这两个资料,进行了简单分析. ******************************************************** ...

  8. C语言中的内存分配与释放

    C语言中的内存分配与释放 对C语言一直都是抱着学习的态度,很多都不懂,今天突然被问道C语言的内存分配问题,说了一些自己知道的,但感觉回答的并不完善,所以才有这篇笔记,总结一下C语言中内存分配的主要内容 ...

  9. Java中的内存分配机制

    Java的内存分为两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型变量和对象的引用都在函数的栈内存中分配.当在一个代码块中定义一个变量的时候,java就在栈中为其分配内存,当超过作用域的 ...

随机推荐

  1. Python contenttypes组件

    介绍 Django包含一个contenttypes应用程序(app),可以跟踪Django项目中安装的所有模型(Model),提供用于处理模型的高级通用接口. Contenttypes应用的核心是Co ...

  2. Educational Codeforces Round 32:E. Maximum Subsequence(Meet-in-the-middle)

    题目链接:E. Maximum Subsequence 用了一个Meet-in-the-middle的技巧,还是第一次用到这个技巧,其实这个技巧和二分很像,主要是在dfs中,如果数量减小一半可以节约很 ...

  3. 【14】PNG,GIF,JPG的区别及如何选

    [14]PNG,GIF,JPG的区别及如何选 GIF: 8位像素,256色 无损压缩 支持简单动画 支持boolean透明 适合简单动画 JPEG: 颜色限于256 有损压缩 可控制压缩质量 不支持透 ...

  4. IOS 自动布局-UIStackPanel和UIGridPanel(五)

    试想这样的一个需求场合,一个button靠右显示,并且距离superView的顶部和右边间距分别为10和5.如下图所示: 要实现这样的需求,如果不用自动布局技术,那么我们能想到的就是老老实实的使用绝对 ...

  5. POJ-1743 Musical Theme,后缀数组+二分!

                                                        Musical Theme 人生第一道后缀数组的题,采用大众化思想姿势极其猥琐. 题意:给你n个 ...

  6. BZOJ 3990 [SDOI2015]排序 ——搜索

    [题目分析] 可以发现,操作的先后顺序是不影响结果的,那么答案就是n!的和. 可以从小的步骤开始搜索,使得每一个当前最小的块都是上升的数列,然后看看是否可行即可. 复杂度好像是4^n [代码](哪里写 ...

  7. 常州模拟赛d3t2 灰狼呼唤着同胞

    题目背景 我的母亲柯蒂丽亚,是一个舞者.身披罗纱,一身异国装扮的她,来自灰狼的村子. 曾经在灰狼村子担任女侍的她,被认定在某晚犯下可怕的罪行之后,被赶出了村子. 一切的元凶,都要回到母亲犯下重罪的那一 ...

  8. c++ 多线程:线程句柄可以提前关闭,但是线程并没有关闭

    很多程序在创建线程都这样写的:ThreadHandle = CreateThread(NULL,0,.....);CloseHandel(ThreadHandle );1,线程和线程句柄(Handle ...

  9. iOS 收款计算器算法

    一个收款计算器算法,从之前高仿有赞Demo里面抽离的一个界面 demo 在这里 https://github.com/L-vinCent/calculView_function 显示计算记录 不能连续 ...

  10. Explosion at Cafebazaar

    Explosion at Cafebazaar 时间限制: 1 Sec  内存限制: 128 MB 题目描述 You are an engineer at Cafebazaar and your sp ...