C语言【枚举、联合】

简介: 枚举顾名思义就是一一列举。把可能的取值一一列举。比如我们现实生活中:一周的星期一到星期日是有限的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,当然在定义的时候也可以赋初值

🌰(默认是从0开始的)


enum Sex//性别
{
  MALE,
  FEMALE,
  SECRET
};
int main()
{
  enum Sex sex;
  //验证默认是从0开始的
  printf("%d\n", MALE);
  printf("%d\n", FEMALE);
  printf("%d\n", SECRET);
  return 0;
}
运行结果:
*****
0
1
2
*****

🌰(赋值开头)


#include<stdio.h>
enum Sex//性别
{
  MALE = 1,
  FEMALE,
  SECRET
};
int main()
{
     enum Sex sex;
    //开头赋值的情况
  printf("%d\n", MALE);
  printf("%d\n", FEMALE);
  printf("%d\n", SECRET);
  return 0;
}
运行结果:
*****
1
2
3
*****

🌰(中间赋值)


#include<stdio.h>
enum Sex//性别
{
  MALE ,
  FEMALE = 0,
  SECRET
};
int main()
{
     enum Sex sex;
    //中间赋值的情况
  printf("%d\n", MALE);
  printf("%d\n", FEMALE);
  printf("%d\n", SECRET);
  return 0;
}
运行结果:
*****
0
0
1
*****

总结:


枚举类型和结构体类型很相似,只过是结构体内部是成员,枚举内部是枚举常量(该类型可能出现的情况)

枚举常量默认是从1依次往下增大的,但是我们也可以赋初值(初始化),但之后就不能改变

.赋初值的位置不同,产生的结果也就不同;在开头赋初值,依次往下递增;在中间赋初值,开头是0,往下递增,赋初值的地方依次往下递增


枚举的优点

其实,在我们不了解枚举类型的情况下,我们一般都是用#define 定义常量,那么枚举类型相比于它又有什么优点呢?


枚举的优点:

1.增加代码的可读性和可维护性

2.和#define定义的标识符比较枚举有类型检查,更加严谨。

3.防止了命名污染(封装)

4.便于调试

5.使用方便,一次可以定义多个常量

🌰(便于调试)


#define MAX 100
//这种情况下,在调试的时候所有的MAX都消失,直接变成100
//且没有#define MAX 100这段代码,不方便调试
enum max
{
  MAX=100,
};
//记住枚举是一种类型,在调试的过程中比不会消失,方便调试

🌰(增加代码的可读性与可维护性)


//假如,我们在写一个菜单
//第一种方法:
#include<stdio.h>
int main()
{
  printf("**************1.add   2.sub************\n");
  printf("**************3.mul   4.div************\n");
  printf("****************  0.exit **************\n");
  int input = 0;
  scanf("%d", &input);
  switch (input)
  {
    case 1;
      break;
    case 2;
      break;
    case 3;
      break;
    case 4;
      break;
    case 0;
      break;
  }
  //这种情况下,我们会忘记每个数字代表的操作是什么
}
//第二种方法:
#include<stdio.h>
int main()
{
  printf("**************1.add   2.sub************\n");
  printf("**************3.mul   4.div************\n");
  printf("****************  0.exit **************\n");
  int input = 0;
  scanf("%d", &input);
  enum Option
  {
    exit,
    add,
    sub,
    mul,
    dix
  };
  switch (input)
  {
    case add;
      break;
    case sub;
      break;
    case mul;
      break;
    case div;
      break;
    case exit;
      break;
  }
  //这种情况下,进行的操作和上面的是一样的效果
  //但更清楚明了每一步要进行的操作是什么
}

枚举的使用

只能拿枚举常量给枚举变量赋值,才不会出现类型的差异


🌰


#include<stdio.h>
enum color
{
  green = 1,
  red = 5,
  yellow = 4,
  blue
};
int main()
{
  enum color col = blue;
  col = 5;  //ok???
  //虽然blue 和 5 的值是一样的
  //但是,第一种情况下直接让col 是blue的值
  //而第二种情况下,red跟blue都是5,会产生歧义,而且会产生类型上的差异
  return 0;
}

联合类型的定义

联合也是一种特殊的自定义类型

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

联合的关键字是union

🌰

#include<stdio.h>
//联合的声明
union UN
{
  int a;
  char b;
};
int main()
{
  //联合变量的定义
  union UN un;
  //联合变量大小的计算
  printf("%d\n", sizeof(un));
  return 0;
}
//运行结果:
*****
4
*****

在这里,我们不禁有一个疑问:


联合的成员在内存中是怎样存储的?

上面例子中,联合变量的大小为什么是4,而不是5?


联合的特点

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


🌰


#include<stdio.h>
union UN
{
  int a;
  char b;
};
int main()
{
  union UN un;
  printf("%p\n", &un);
  printf("%p\n", &(un.a));
  printf("%p\n", &(un.b));
  return 0;
}
运行结果:
*****
012FFC94
012FFC94
012FFC94
*****

94ec93572da84347be6a8452dd2865b2.png


从这个例子说明,联合的每次只能单独出现一个出现一个变量,不然的话,进行不同的操作会导致内存紊乱


🐉🐉🐉🐉🐉

那看到这里,不得不提一下联合的一个巧妙用法 ----- 判断当前机器的大小端:

//判断当前机器的大小端
#include<stdio.h>
union Clc
{
  char a;
  int b;
};
int main()
{
  union Clc clc;
  clc.b = 1;
  if (clc.a == 1)
    printf("小端\n");
  else
    printf("大端\n");
  return 0;
}


联合大小的计算

联合的大小至少是最大成员的大小。

当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。


🌰


#include<stdio.h>
union UN1
{
  short arr[5];
  int b;
};
union UN2
{
  char arr[6];
  int b;
};
int main()
{
  printf("%d\n", sizeof(union UN1));
  printf("%d\n", sizeof(union UN2));
  return 0;
}
//运行结果:
*****
12
8
*****

原因分析:

ecff130e991a4d65bd063753bd74b6bf.png


自定义类型的总结:


结构体的大小存在对其行为

位段的大小不存在对齐行为

枚举的大小就是整形变量的大小,4个字节

联合的大小存在对其行为

149d99aabd0f4499a2f95ef833119acb.jpeg


相关文章
|
11天前
|
存储 编译器 C语言
c语言回顾-联合和枚举
c语言回顾-联合和枚举
24 4
|
11天前
|
存储 C语言 C++
深入C语言,发现多样的数据之枚举和联合体
深入C语言,发现多样的数据之枚举和联合体
深入C语言,发现多样的数据之枚举和联合体
|
5月前
|
存储 安全 编译器
C语言(13)----联合和枚举
C语言(13)----联合和枚举
37 1
|
17天前
|
存储 安全 编译器
深入理解C语言中的枚举
深入理解C语言中的枚举
|
19天前
|
存储 编译器 C语言
【C语言】自定义类型:联合与枚举的简明概述
【C语言】自定义类型:联合与枚举的简明概述
|
2月前
|
存储 编译器 C语言
【C语言篇】自定义类型:联合体和枚举详细介绍
像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以不同的类型。
40 1
|
4月前
|
C语言
枚举(C语言)
枚举(C语言)
|
4月前
|
编译器 C语言 C++
【C语言基础】:自定义类型(二) -->联合和枚举
【C语言基础】:自定义类型(二) -->联合和枚举
|
4月前
|
C语言
C语言学习记录——枚举(定义、与结构体的区别、优点)
C语言学习记录——枚举(定义、与结构体的区别、优点)
50 3
|
4月前
|
C语言
深入挖掘C语言之——枚举
深入挖掘C语言之——枚举
24 1