C语言位段

Posted QtHalcon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

空间分布为:

 

 

以上是关于C语言位段的主要内容,如果未能解决你的问题,请参考以下文章

C语言位段

C语言位段

梦开始的地方 —— C语言(枚举+位段+联合体)

[C语言学习]位段

C语言中的位段操作—嵌入式学习(实习篇)

C语言 段位