从网上看到这样一段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. 对于js运动中产生的问题

    1.不同的对象调用同一个定时器情况,则需要将定时器的名称定为该对象的一个属性来进行运用. 例: <!DOCTYPE html> <html lang="en"&g ...

  2. JavaScript正则表达式-字符类

    字符列表 在方括号内指定一个或者多个字符组成的字符列表,与字符列表中任意字符匹配,都被认为是匹配的.每次匹配只能匹配列表中的一个字符. str = "bird,head,fed,meadow ...

  3. 修改JVM的参数、Jstat、Jstack、gclog

    ---恢复内容开始--- 1. jetty 修改JVM的参数 deploy/bin/env.sh 在上面的环境变量脚本中进行修改:如果分配给JVM的内存是4g 这个里面的JAVA_OPTS 的配置项就 ...

  4. 【02】markdown工具推荐

    [02]信息 Windows 平台 MarkdownPad MarkPad Linux 平台 ReText Mac 平台 Mou 最新版Mac OS下Mou已经无法使用了.这里推荐一个跨平台的编辑器  ...

  5. IOS 自动布局-UIStackPanel和UIGridPanel(四)

    为什么说scrollview的自动化布局是难点? 对scrollview做自动化布局,无非就是想对scrollview里面的subviews来做自动化布局.但是scrollview里面的subview ...

  6. A. Light Bulb

    A. Light Bulb Time Limit: 1000ms Case Time Limit: 1000ms Memory Limit: 32768KB   64-bit integer IO f ...

  7. D. Frequent values

    D. Frequent values Time Limit: 3000ms Case Time Limit: 3000ms Memory Limit: 131072KB   64-bit intege ...

  8. apr的使用

    APR(Apache Portable Runtime),即Apache可移植运行库,正如官网所言,APR的使命是创建和维护一套软件库,以便在不同操作系统(Windows.Linux等)底层实现的基础 ...

  9. ffmpeg常见名词解析

    scan_all_pmts, 扫描全部的ts流的"Program Map Table"表.

  10. 【C#】穿马甲的流程控制语句

    导读:话说当年选择.顺序.循环语句风靡整个VB,今年发现,那几个东西又换了件衣服,跑到了C#里蹦跶.开始,真被这几个穿马甲的吓了一跳,没看出来这是老伙伴.突然有一天,瞥见了脱下新衣的孩子们.哈哈哈哈. ...