自定义数据类型-枚举和联合
Suzhou 34 1
枚举

枚举关键字是enum。 枚举类型的定义:

enum Color
{
    RED,  //0
    GREEN,  //1
    BLUE  //2
};

int main()
{
    enum Color c = RED;
    printf("%d %d %d", RED, GREEN, BLUE);  //0 1 2
    return 0;
}

::: tip 上述代码中,枚举的类型是enum Color。RED、GREEN、BLUE是枚举可能出现的取值,称为枚举常量。枚举的定义变量和结构体相似。枚举定义的变量赋值时只能枚举常量中找。 ::: 上述代码打印的枚举常量的值是自上而下从0开始递增赋值的。也可以在定义时对枚举常量赋初始值,如RED=10。枚举常量赋初始值后不能被修改。

如果给某一个枚举常量赋值,该枚举常量前面的值由0开始向下递增,该枚举常量后面的值从该枚举常量赋值的基础上向下递增。如给GREEN赋值10,RED的值仍为0,BLUE的值变为11。

::: tip 枚举的优点: - 增加代码的可读性和可维护性。 - 和#define定义的标识符比较,枚举有类型检查,更加严谨。 - 防止了命名污染(封装)。 - 便于调试。 - 使用方便,一次可以定义多个常量。 :::

enum Color
{
    RED,
    GREEN = 10,
    BLUE
};

int main()
{
    enum Color c = RED;
    printf("%d %d %d", RED, GREEN, BLUE);  //0 1 2
    return 0;
}
#define RED 0
#define GREEN 1
#define BLUE 2
int main()
{
    enum Color c = RED;
    printf("%d %d %d", RED, GREEN, BLUE);  //0 1 2
    return 0;
}

使用define定义时,在程序编译过程中,显示的是预编译后的程序,如上述代码第6行,在预编译时,系统会将RED替换成0,即在系统编译时看到的第6行代码是enum Color c = 0。 ::: tip C语言的编译过程主要分为四个步骤:预处理、编译、汇编、链接。 :::

语法定义枚举中成员大小是一个整形

enum Sex
{
    MALE,
    FEMALE,
    SECRET
};
int main()
{
    enum Sex s = MALE;
    printf("%d\n", sizeof(s));  //4
    return 0;
}

联合

联合也叫联合体、共用体。 联合体中的成员共有一个空间,如下:

union UN
{
    char a;
    int b;
};
int main()
{
    union UN u;
    printf("%d\n", sizeof(u));

    printf("%p\n", &u);
    printf("%p\n", &u.a);
    printf("%p\n", &u.b);
    return 0;
}
4
00000037E66FF524
00000037E66FF524
00000037E66FF524

如上述代码,第9行结果表示联合体开辟一块4字节的空间,第11、12、13行代码结果表示,成员起始位置相同,可能存放情况如下: 自定义数据类型-枚举和联合

在同一时刻,联合体中的成员只有一个可以被使用。

使用联合体检测系统存储模式:

int check_sys(int a)
{
    union UN  //可以省略UN,匿名创建联合体变量只能使用一次
    {
        char m;
        int n;
    }u;  //类型直接创建变量
    u.n = a;
    return u.m;
}
int main()
{
    int a = 1;
    int ret = check_sys(a);
    if (ret == 0)
    {
        printf("大端");
    }
    else
    {
        printf("小端");
    }
    return 0;
}

上述代码利用联合体的特点,当整个字节赋值1时,01 00 00 00填充进每一个字节,如果第一个字节是01,就是小端存储,如果第一个字节不是01,就是大端存储。即可以通过返回第一个字节的值进行判断。

联合体大小计算规则

  • 联合体的大小至少是最大成员的大小。
  • 当最大成员的大小不是最大对齐数的整数倍时,要对齐到最大对齐数的整数倍。
    union UN
    {
      int a;
      char arr[5];
    };
    int main()
    {
      union UN u;
      printf("%d\n", sizeof(u));  //8
      return 0;
    }
    上述代码输出结果是8字节。
  • 上述代码中,int a占4字节,char arr[5]占5字节,即共用5字节就够了。a的对齐数是4,VS对齐数是8,取4,arr的对齐数是1,VS的对齐数是8,取1,整个联合体的对齐数取最大对齐数4。根据联合体大小计算规则第二条,5字节不是4的倍数,取最小整数倍,即8字节。*
评论区

索引目录