亲宝软件园·资讯

展开

C语言位段

暴躁小程序猿 人气:1

一、位段是什么

位段的声明和结构是类似的,有两个不同

1.位段的成员必须是 int、unsigned int 或signed int 。

2.位段的成员名后边有一个冒号和一个数字。

举例如下:

struct A
{
    int _a:2;
    int _b:5;
    int _c:10;
    int _d:30;
    };

这个A就是一个位段。

但是结构体可以根据结构体内存对齐确定一个结构体的大小,但是位段的大小怎么确定呢?

位段A的大小是多少呢?

printf("%d\n", sizeof(struct A));

我们利用sizeof操作符来测一下这个A位段的大小是8个字节

但是根据常理来说应该是16个字节呀,我们和结构体对比分析

struct s
{
    int a;
    int b;
    int c;
    int d;
    };
   int main()
   {
     printf("%d\n", sizeof(struct s));//16个字节
     return 0;
     }

对比发现位段不是根据他的数据类型来分配内存的。接下来我们看看位段是怎么分配内存的。

二、位段的内存分配

2.1位段内存分配的原则

  1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
  2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
  3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。ps:虽然位段是不跨平台的,但是我们可以根据平台的不同编写不同的代码
struct A
{
    int _a:2;     //虽然a是int型但是他所分配的内存根据冒号之后的数字确定,a冒号后面是2,所以他只占用2个比特位
    int _b:5;    //同理,b成员只需要5个比特位
    int _c:10;    //10个比特位
    int _d:30;    //30个比特位
    };

  那么我们发现这个字段A一共需要47个比特位,好像6个字节就可以完成存储,但是事实并非如此,我们根据位段的内存分配原则,位段的成员是int类型所以按照需要以4个字节的方式开辟,我们先开辟4个字节的空间,即32个比特位,我们可以存储a,b,c但是存储d的时候发现内存不够了,我们再次按照需求再一次开辟4个字节的空间,最终开辟了8个字节的空间而非6个字节的空间来存储位段A。

  但是a,b,c存储之后还剩下15个比特位,这些比特位还用不用呢?

  答案是不确定的,每个编译器的处理方式都是不一样的,在VS环境下就浪费掉了,位段依旧有很多的不确定性。下面用图例理想表示一下在VS环境下位段的存储:

代码如下:

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
struct S
{
  	char a : 3;    //a占3个比特位,以下同理
  	char b : 4;    
  	char c : 5;
  	char d : 4;
};
int main()
{
//printf("%d\n", sizeof(struct S));
	struct S s = { 0 };
	s.a = 10;       // 赋值给位段的成员
	s.b = 12;
	s.c = 3;
	s.d = 4;
  return 0;
}

2.2位段内存分配图解

假设内存都是由低位向高位使用的,即从右向左使用:

我们将这3个字节的内存中都用0进行初始化:

struct S s = {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> 0 };

三、位段的跨平台问题

int 位段被当成有符号数还是无符号数是不确定的。

int的最高位原本是符号位,但是int位段是有符号数还是无符号数是不确定的。位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题。

(16位机器最大可以处理16位数据,寻址空间也只有16位,但是如果传入27位数据就会出问题)

ps:int在16位操作系统下占2个字节。位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。

上图只是假设我们从右向左使用,但是分配表示尚未定义,所以也是不确定的。当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。

总结:

  跟结构相比,位段可以达到同样的效果,但是可以很好的节省空间,但是有跨平台的问题存在。

  牺牲了它的可移植性,但是节省了空间,可以根据需求选择。

  为什么说和结构相比,位段可以节省空间呢?

代码如下(示例):

struct A
{
    int _a:2;     //虽然a是int型但是他所分配的内存根据冒号之后的数字确定,a冒号后面是2,所以他只占用2个比特位
    int _b:5;    //同理,b成员只需要5个比特位
    int _c:10;    //10个比特位
    int _d:30;    //30个比特位
    };

  比如这个代码,假设a的取值只可能是0,1,2,3,如果用结构写的话会给a分配4个字节的空间也就是32个比特位,但是a最大需要的比特位是2位,所以会大大造成浪费,并且结构体还存在结构体内存对齐问题,牺牲了空间提高了时间效率。

四、位段的使用

总结

  位段的介绍到此结束,总结一下就是位段相比较结构体节省了空间但是失去了可移植性,存在了跨平台的问题,我们可以根据自身的需求来选择是否使用位段,同时位段广泛使用在计算机网络方面,如果想变强就需要学会合理使用位段,加油 少年们!

加载全部内容

相关教程
猜你喜欢
用户评论