C语言单片机实际应用基础--位域(位段)

应用场景

数据仅需要0和1表示,例如:开关通电和断电两种状态,用 0 和 1 表示,用一个二进位。

位域实例

结构体定义

struct bs{
    unsigned int m;
    unsigned int n: 4;
    unsigned char ch: 6;
};

m:占用 4 个字节(Byte)的内存;

n:“:”后面的数字限定n占用的位数,不能再根据数据类型计算长度,n占用4位(Bit)内存;

ch:占用6位(Bit)内存。

#include 

int main(){
    struct bs{
        unsigned m;
        unsigned n: 4;
        unsigned char ch: 6;
    } a = { 0xad, 0xE, '$'};
   
 //第一次输出
    printf("%#x, %#x, %c\n", a.m, a.n, a.ch);
    
//更改值后再次输出
    a.m = 0xb8901c;
    a.n = 0x2d;
    a.ch = 'z';
 //第二次输出 
printf("%#x, %#x, %c\n", a.m, a.n, a.ch);

    return 0;
}

运行结果:

0xad, 0xe, $
0xb8901c, 0xd, :

对于 n 和 ch,第一次输出的数据:完整,第二次输出的数据:不完整。
第一次输出:n值 0xE,二进制 1110、ch 值0x24('$' ASCII 码 0x24)二进制10 0100,不超出限定位数,能正常输出。
第二次输出:n值0x2d,二进制10 1101、ch 值0x7a('z'  ASCII 码为0x7a),二进制111 1010,都超出限定的位数,仅留下未超出部分 1101、11 1010,十六进制为:0xd、0x3a(0x3a 对应的字符是 :)。

C语言标准规定

1)位域的宽度不能超过它所依附的数据类型的长度。通俗地讲,成员变量都是有类型的,这个类型限制了成员变量的最大长度,“:”后面的数字不能超过这个长度。

2)只有有限的几种数据类型可以用于位域。在 ANSI C 中,这几种数据类型是 int、signed int 和 unsigned int(int 默认就是 signed int);到了 C99,_Bool 也被支持了。

3)编译器在具体实现时都进行了扩展,额外支持了 char、signed char、unsigned char 以及 enum 类型,所以上面的代码虽然不符合C语言标准,但它依然能够被编译器支持。

你可能感兴趣的:(代码学习)