C语言位段

        有时,存储1个信息不必占用1个字节,只需二进制的1个(或多个)位就够用。如果仍然使用结构类型,则造成内存空间的浪费。
为此,C语言引入了位段类型。

位段的概念与定义

        所谓位段类型, 是一种特殊的结构类型,其所有成员均以二进制位为单位定义长度,并称成员为位段。
        例如,CPU的状态寄存器,按位段类型定义如下:

struct status
{
    unsigned sign:1;/*符号标志*/
    unsigned zero:1;/*零标志*/
    unsigned carry:1;/*进位标志*/
    unsigned parity:1/*奇偶溢出标志*/
    unsigned half_carry:1;/*半进位标志*/
    unsigned negative:1; /* 减标志*/
} flags;

内存分布

内存分布按照内存对齐原则

struct data{
    unsigned char f1:1;
    unsigned char f2:2;
};
cout<<sizeof(struct data); //1

匿名位段

匿名位段就是没有变量名,用填充空间,是空间字节对齐

struct data{
    unsigned short f1:4;
    unsigned short   :4;
    unsigned short   :4;
    unsigned short f4:12;
};

位扩展问题

struct data{
             short int n:1;
    unsigned short int x:1;
};

当用成员给其他非位段变量赋值时要进行位扩展

位段有符号——》被赋值无符号   (由于n为有符号数,所以n先被扩展为1111 1111,a再取值)

    struct data node;
    node.n = 3;
    unsigned short int a = node.n;
    cout<<a;   //65535

位段有符号——》被赋值有符号   (由于n为有符号数,所以n先被扩展为1111 1111,a再取值)

    struct data node;
    node.n = 3;
    short int a = node.n;
    cout<<a;   //-1

位段无符号——》被赋值无符号   (由于x为无符号数,所以n先被扩展为0000 0001,a再取值)

    struct data node;
    node.x = 3;
    unsigned short int a = node.x;
    cout<<a;   //1

位段无符号——》被赋值有符号   (由于x为无符号数,所以n先被扩展为0000 0001,a再取值)

    struct data node;
    node.x = 3;
    unsigned short int a = node.x;
    cout<<a;   //1

以下几点要注意

位段成员必须是整型或者字符型,不能是浮点型。

由于位段成员没有地址,所以不能求对位段成员求地址,不能通过scanf读入位段值,不能用指针指向位段成员。但是非位段成员可以取地址。

char类型的位段不能横跨两个字节,如下面程序

struct char_data{
    unsigned char x:4;
    unsigned char y:5;
};
int main(void)
{
    unsigned char str[2];
    struct char_data *p = (struct char_data *)str;
    memset(str, 0, 2);
 
    p->x = 18;
    p->y = 4;
    cout<<(int)p->x  <<" "<<(int)p->y<<endl; //2 4
    cout<<(int)str[0]<<" "<<(int)str[1];     //2 4
}

空间分布为:

猜你喜欢

转载自blog.csdn.net/qq_40732350/article/details/123334196
今日推荐