位段

什么是位段?
——位段是一种类似结构体的类型。

位段的声明和结构体类似,但有两点不同:

  • 位段的成员必须是int、unsigned int或signed int(可能也有char,但是一个位段的类型必须是类似的)
  • 位段的成员名后边有一个冒号和一个数字(意思是这个变量需要多少个比特位)

位段的内存分配

  • 位段的成员可以是int、unsigned int、signed int或者是 char类型
  • 位段的空间上是按照需要以4个字节(int)或1个字节(char)的方式来开辟的
  • 位段涉及很多不确定因素,不跨平台,注重可移植性程序不使用位段
1234567891011121314
#include <stdio.h>//位段 - 二进制位struct S{    int a : 2;//需要2个比特位    int b : 5;//需要5个比特位    int c : 10;//需要10个比特位    int d : 30;//需要30个比特位};int main() {    struct S s;    printf("%d\n",sizeof(s));//8    return 0;}

打印的结果是s使用8字节空间。
首先开辟一个4字节的空间,共32bit,先给a,b,c分配共17bit的空间,剩下的空间不够给d分配30bit的空间,剩余空间丢弃。
另开辟一块4字节的空间,共32bit,给d分配30bit的空间,剩下2bit的空间丢弃,所以位段s占8字节。
注意⚠️:位段后面的数字不能大于32。

123456789101112131415161718
#include <stdio.h>struct S{    char a : 3;    char b : 4;    char c : 5;    char d : 4;}; int main(){    struct S s ={0};    s.a = 10;//10的二进制是1010,但a这个空间只存的下3个比特位,只能存的下010,也就是2    s.b = 20;//20的二进制是10100,b只有4比特位,存0100。    s.c = 3;    s.d = 4;    return 0;}

位段的跨平台问题

位段不跨平台,主要由下面四点导致:

  • int位段被当成有符号还是无符号数是不确定的。
  • 位段中最大位的数目不能确定。(16位机器最大16,32位机最大32,写成27,在16位机器会出问题。)
  • 标准未定义位段在内存中的分配规则,不知道从左往右还是从右往左分配
  • 一个结构包含两个位段,第二个成员较大时,无法容纳第一个位段剩余位时,剩下的空间舍弃或保留不确定。
🔍 ×