枚举和联合体

枚举和联合体

枚举

枚举顾名思义就是一一列举。把可能的取值一一列举出来。
比如,现实生活中:

  • 一周的星期一到星期日是有限的7天,可以一一列举。
  • 性别有:男、女、保密,也可以一一列举。
  • 月份有12个月,也可以一一列举。
  • 颜色也可以一一列举。
  • ……

枚举的定义

enum Day  //星期
{
    Mon,
    Tues,
    Wed,
    Thur,
    Fri,
    Sat,
    Sun
};

enum Sex  //性别
{
    MALE,
    FEMALE,
    SECRET
};

enum Color //颜色
{
    RED,
    GREEN,
    BLUE
};

以上定义的 enum Day,enum Sex,enum Color 都是枚举类型
{}中的内容是枚举类型的可能取值,也叫枚举常量。这些可能取值都是有值的,默认从0开始,一次递增1。比如:

typedef enum Color
{
    RED,
    GREEN,
    BLUE
}color_t;
int main()
{
    color_t clr = RED;
    printf("RED=%d\n", clr);
    printf("GREEN=%d\n", GREEN);
    printf("BLUE=%d\n", BLUE);
    system("pause");
    return 0;
}
// 结果:RED=0
//      GREEN=1
//      BLUE=2

当然在定义的时候也可以赋初值。比如:

enum Color{ RED=2, GREEN=10, BLUE };
int main()
{
    printf("RED=%d\n", RED);
    printf("GREEN=%d\n", GREEN);
    printf("BLUE=%d\n", BLUE);
    return 0;
}
//结果:RED=2
//     GREEN=10
//     BLUE=11

枚举的优点

  1. 增加代码的可读性和可维护性。
  2. 跟 #define 定义的标识符比较枚举有类型检查,更加严谨。
  3. 进行了封装,防止了命名污染。
  4. 便于调试。
  5. 使用方便,一次可以定义多个常量。

联合体

联合体的定义

联合体也是一种特殊的自定义类型。
这种类型定义的变量也包含一系列的成员,特征是这些成员共用同一块内存空间(所以联合体也叫共用体)。
比如:

//联合类型的声明
union Un
{
    char c;
    int i;
};

//联合变量的定义
union Un un;
//计算联合变量的大小
printf("%d\n", sizeof(un)); // 4

联合的特点

联合的成员共用同一块内存空间,这样一个联合变量的大小,至少是最大成员的大小(因为联合体至少得有能力保存最大的那个成员)

union Un
{
    char c;
    int i;
};
int main()
{
    union Un un;
    //下面输出的结果是一样的吗?
    printf("%x\n", &(un.i));
    printf("%x\n", &(un.c));
    //一样,即 &(un.i)=&(un.c)=&un
    //因为它们共用同一块内存空间,取地址时,取得都是首元素的地址。

    un.i = 0x11223344;
    un.c = 0x55;
    printf("%x\n", un.i); // 0x11223355(小端情况下)
    return 0;
} 

联合体大小的计算

  • 联合体的大小至少是最大成员的大小。
  • 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
1union Un1
{
    char c[5]; //5
    int i;     //4
};
printf("%d\n", sizeof(union Un1)); // 8

解析:

第一步,联合体的大小至少是5;
第二步,因为5不是最大对齐数4的倍数,所以就要让它对齐到4的比5大的最小的倍数。即是8.

2union Un2
{
    short c[7]; // 2*7=14
    int i;      // 4
};
printf("%d\n", sizeof(union Un2)); // 16

解析:

第一步,联合体的大小至少是14;
第二步,因为14不是最大对齐数4的倍数,所以就要让它对齐到4的比14大的最小的倍数。即是16.

3:联合体与结构体巧妙的结合

//将long类型的IP地址,转换成点分十进制的表示形式
union ip_addr
{
    unsigned long addr;
    struct
    {
        unsigned char c1;
        unsigned char c2;
        unsigned char c3;
        unsigned char c4;
    }ip;
};

int main()
{
    union ip_addr my_ip;
    my_ip.addr = 176238749;
    printf("%d.%d.%d.%d\n", my_ip.ip.c4, my_ip.ip.c3, my_ip.ip.c2, my_ip.ip.c1);
    system("pause");
    return 0;
}
// 结果:10.129.48.157

你可能感兴趣的:(C语言)