枚举与位段

本文探讨了C语言中的枚举类型及其优点,包括增强代码可读性、类型检查、防止命名污染和方便调试。同时,还介绍了联合体(共用体)的概念,指出其大小至少为最大成员的大小,并讨论了位段的特性,如成员类型限制及跨平台问题。枚举和位段在编程中提供了灵活的常量定义和数据存储方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

枚举类型的定义

#include <stdio.h>
enum color
{ //枚举的可能取值
    blue,         //  ,号分隔
    red, 
    yellow
 };
enum S
{
    a =17,    
    b=20,
    c=16
};
int main()
{
    printf("%zd\n", sizeof(color)); //4
    printf("%zd\n", sizeof(blue));  //4,枚举类型的大小为整形大小
    printf("%d %d %d\n", blue,red,yellow); //初始值按顺序排默认为blue--0 red--1 yellow--2
    //enum S a = 12;  //error--"int" 类型的值不能用于初始化 "S" 类型的实体,不能再内部定义
    printf("%d %d %d\n",a,b,c);            //初始值可以在前面自定义
    return 0;
}

可以使用define,为什么还要用enum
枚举的优点
1.增强代码的可读性和可维护性
2.和define定义标识符相比,枚举有类型检查,更加严谨、
3.防止了命名污染(封装)
4.便于调试
5.使用方便,一次可以定义多个常量

联合(联合体,共用体)
这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间
联合体的大小至少是最大成员的大小
当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍联合类型的声明

#include <stdio.h>
union S
{
    char c;
    int a;
};
union M
{
    int a;    //a的最大对齐数是4
    char n[5];//n[5]的最大对齐数是1,相当于定义五个char
};                          //M的最大对齐数是4,而4字节放不下n,需要再开辟4个字节空间
int main()
{
    union S m;
    union M x;
    printf("%p\n", &m);
    printf("%p\n", &(m.c));
    printf("%p\n", &(m.a)); //三个的地址相同,c和a共用了同一块空间,都从起始位置往后放

    printf("%zd\n", sizeof(S)); //--4
    printf("%zd\n", sizeof(m)); //--4
    printf("%zd\n", sizeof(x)); //8
    
    return 0;
}


位段--二进制位
位断的声明和结构是类似的,有两个不同
1.位段的成员必须是相同类型的(int,unsigned int或signed int)
2.位段的成员名后边有一个冒号和一个数字
3.设置可移植程序时尽量别用位段,不同编译器不一样

#include <stdio.h>
struct A
{
    int a : 2;  //a占2个比特位
    int b : 5;  //b占5个比特位
    int c : 10; //10个
    int d : 30; //30个  共47bite
};              //int类型 先开辟4个字节(32bite)空间 不够后又加4字节空间
                //节省空间的同时允许浪费空间
int main()
{
    int a = 100;
    struct A m;
    printf("%zd\n", sizeof(A));
    printf("%zd\n", sizeof(m));    //8个字节
    return 0;
}

位段的跨平台问题
int 当成有符号数还是无符号数不能确定
位段中最大位数的数目不能确定
位段中的成员在内存中的分配从左向右还是从右向左不能确定
......... 

#include <stdio.h>
struct s
{
    char a : 3;
    char b : 4;
    char c : 5;
    char d : 4;
};
int main()
{
    struct s n = {0};
    n.a = 10;
    n.b = 20;
    n.c = 3;
    n.d = 4;
    return 0;
}
struct S
{
    char a;   //1字节
    char b:1;
    char c : 2;
    char d : 3;
}*p;//共两个字节

#include <stdio.h>
#include <string.h>

int main()
{
    char arr[4];
    memset(arr, 0, 4);//把arr的四个字节设置为0
    //arr 00000000 00000000 00000000 00000000
    //           a   d  c b 第一个字节给a 第二个字节最后的bit给b,依次类推
    p=(struct S*)arr; //将数组arr强制转化为(struct S*)类型赋给p
    //p   00000000 00000000 00000000
    p->a = 2;
    p->b = 3;//11 而b只花一个比特存储,于是只存1
    p->c = 4;//100 两个比特位 放00
    p->d = 5;//101 三个比特位 放101
    //p   00000010 00101001 00000000
    printf("%02x %02x %02x %02x\n",arr[0],arr[1],arr[2],arr[3]);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值