随笔 - 2146  文章 - 19 评论 - 11846 阅读 - 1267万


所有基础的数据类型, 最大的也不过 10 个字节;
我们可以自定义的数据类型 -- "结构", 通过把若干类型组合在一起, 让一种类型可以大很多.

我们知道, 一个字节有八个 Bit 组成; 能否把一种类型缩小、缩小到 Bit 级?
结构中的 "位字段" 是以 Bit 为单位的, 这已经是计算机的最小单位, 大小是 char 类型的 1/8.

下面的例子中定义的位字段, 分别有 1-4 Bit 大小; 1 Bit 的字段只能放两个数(0、1), 4 Bit 的字段也只能放下 16 个数:

1. 结构体可以包含位字段:
#include <stdio.h>

int main(void)
{
    struct Bit {
        unsigned a: 1; /* 1 Bit, 取值范围: 0 - 1  */
        unsigned b: 2; /* 2 Bit, 取值范围: 0 - 3  */
        unsigned c: 3; /* 3 Bit, 取值范围: 0 - 7  */
        unsigned d: 4; /* 4 Bit, 取值范围: 0 - 15 */
    } B;

    B.a = 1;
    B.b = 3;
    B.c = 7;
    B.d = 15;

    printf("%d, %d, %d, %d\n", B.a, B.b, B.c, B.d);

    getchar();
    return 0;
}


上例中, 位域的类型被指定为是无符号的整型(unsigned int), 我试着只要是整型都可以, 但要一致.

假如我们定义 8 个字段, 每个字段都是 1 Bit, 就可以很好地明细一个字节, 譬如:
11111111B = 255;
00000001B = 1;
00001111B = 15;
01111111B = 127;

下面的例子用程序对上面的说明做了落实:

2. 用 8 个 Bit 构成一个 unsigned char 数:
#include <stdio.h>

int main(void)
{
    struct Bit {
        int b8: 1;
        int b7: 1;
        int b6: 1;
        int b5: 1;
        int b4: 1;
        int b3: 1;
        int b2: 1;
        int b1: 1;
    } B;
    
    unsigned char *p = NULL;

    B.b1 = 1; B.b2 = 1; B.b3 = 1; B.b4 = 1; B.b5 = 1; B.b6 = 1; B.b7 = 1; B.b8 = 1;
    p = (unsigned char *)&B;
    printf("%d\n", *p);  /* 255 */

    B.b1 = 0; B.b2 = 0; B.b3 = 0; B.b4 = 0; B.b5 = 0; B.b6 = 0; B.b7 = 0; B.b8 = 1;
    p = (unsigned char *)&B;
    printf("%d\n", *p);  /* 1   */

    B.b1 = 0; B.b2 = 0; B.b3 = 0; B.b4 = 0; B.b5 = 1; B.b6 = 1; B.b7 = 1; B.b8 = 1;
    p = (unsigned char *)&B;
    printf("%d\n", *p);  /* 15  */

    B.b1 = 0; B.b2 = 1; B.b3 = 1; B.b4 = 1; B.b5 = 1; B.b6 = 1; B.b7 = 1; B.b8 = 1;
    p = (unsigned char *)&B;
    printf("%d\n", *p);  /* 127 */

    getchar();
    return 0;
}


3. 包含位字段的结构和其他结构没有区别, 譬如同时包含其他类型的字段:
#include <stdio.h>

int main(void)
{
    struct Bit {
        unsigned b1: 1;
        unsigned b2: 1;
        float f;
    } B;
    
    B.b1 = 0;
    B.b2 = 1;
    B.f = 3.14;
    
    printf("%d, %d, %g\n", B.b1, B.b2, B.f); 

    getchar();
    return 0;
}


posted on   万一  阅读(2565)  评论(3编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
历史上的今天:
2007-11-28 刷新网页
2007-11-28 把字符串复制到剪贴板
2007-11-28 如果一个对象不存在


点击右上角即可分享
微信分享提示