目录
一.联合体
1.1 联合体的声明
1.2 联合体的使用
1.3 为什么输出 4呢?
1.4 相同成员的结构体和联合体对比
1.5 联合体大小对比
1.6使用联合体判断大小端
二.枚举类型
2.1枚举类型的例举:
2.2枚举类型的优点
2.3 枚举类型的使用
在上篇文章中已经介绍了结构体。另外,C语言还提供了另外两种数据类型——联合体(union)和枚举(enum),它们各自具有独特的功能和用途。本文将带你深入了解联合体和枚举的概念、用法以及它们在实际编程中的应用。
一.联合体
像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以不同的类型。
但是编译器只为最⼤的成员分配⾜够的内存空间。联合体的特点是所有成员共⽤同⼀块内存空间。
所以联合体也叫:共⽤体。 给联合体其中⼀个成员赋值,其他成员的值也跟着变化。
1.1 联合体的声明
union Un
{
 char c;
 int i;
};
 
1.2 联合体的使用
#include <stdio.h>
//联合类型的声明 
union Un
{
 char c;
 int i;
};
int main()
{
 //联合变量的定义 
 union Un un = {0};
 //计算连个变量的⼤⼩ 
 printf("%d\n", sizeof(un));
 return 0;
} 
输出结果:4
1.3 为什么输出 4呢?
int类型的大小通常是4个字节(byte)。由于联合体的大小至少足够大以容纳其最大的成员,因此Un联合体的大小至少应该是int类型的大小,所以输出为 4。
代码1:
#include <stdio.h>
//联合类型的声明 
union Un
{
 char c;
 int i;
};
int main()
{
 //联合变量的定义 
 union Un un = {0};
 // 下⾯输出的结果是⼀样的吗? 
 printf("%p\n", &(un.i));
 printf("%p\n", &(un.c));
 printf("%p\n", &un);
 return 0;
}
 
输出结果:
012FFD0C
012FFD0C
012FFD0C
这段代码输出了三个地址,它们分别是联合体Un的int成员i的地址、char成员c的地址,以及整个联合体变量un的地址。

代码2:
#include <stdio.h>
//联合类型的声明 
union Un
{
 char c;
 int i;
};
int main()
{
 //联合变量的定义 
 union Un un = {0};
 un.i = 0x11223344;
 un.c = 0x55;
 printf("%x\n", un.i);
 return 0;
}
 
输出结果:
11223355
 
un.i赋值0x11223344,这是一个十六进制数,它会被存储在un联合体所分配的内存中。因为int类型通常占用4个字节,所以0x11223344会被完整地存储在这4个字节中。
然后,代码又对un.c赋值0x55。由于un.c和un.i共享同一块内存,这个赋值会覆盖un.i的最低有效字节(即char类型所占用的字节)。
那么,0x55会覆盖0x11223344的最低字节,变成0x11223355
最后,代码打印un.i的值,由于我们已经修改了它的最低字节,所以输出的是11223355。(小端机器)。
1.4 相同成员的结构体和联合体对比
代码示例:
struct S
{
	char  c;
	int i;
};
struct S s = { 0 };
union Un
{
	char c;
	int i;
};
union Un un = { 0 };
 

1.5 联合体大小对比
• 联合的大小至少是最⼤成员的⼤⼩。
• 当最大成员大小不是最⼤对⻬数的整数倍的时候,就要对齐到最大对齐数的整数倍。
代码示例:
#include <stdio.h>
union Un1
{
	char c[5];
	int i;
};
union Un2
{
	short c[7];
	int i;
};
int main()
{
	//下⾯输出的结果是什么? 
	printf("%d\n", sizeof(union Un1));
	printf("%d\n", sizeof(union Un2));
	return 0;
} 
输出结果:
8
16
由于 char 数组的大小是5个字节,而 int 通常需要4字节对齐,编译器可能会选择增加1个字节的填充(padding),使得整个 union Un1 的大小为8个字节,以满足 int 的对齐要求。
short c[7] 需要14个字节,这超过了 int 的4个字节,所以 union Un2 的大小将是14个字节。与 union Un1 类似,由于内存对齐的原因,编译器可能会增加额外的填充。在这种情况下,编译器可能会添加2个字节的填充,使 union Un2 的总大小为16个字节。
使用联合体可以节省空间。
1.6使用联合体判断大小端
代码示例:
#include <stdio.h>    
  
int check_sys()    
{    
    union    
    {    
        int i;    
        char c[sizeof(int)]; // 使用字符数组以便访问int的各个字节    
    } un;    
    
    un.i = 1; // 设置int为1    
    
    // 检查int的最低有效字节(在小端系统中应该是1)    
    return *(char *)&un.i == 1; // 如果返回true(非零),则是小端系统;如果返回false(零),则是大端系统    
}    
  
int main()    
{    
    if (check_sys()) {    
        printf("这是一个小端系统。\n");    
    } else {    
        printf("这是一个大端系统。\n");    
    }    
    return 0;    
} 
二.枚举类型
枚举类型(enum)是一种用户定义的数据类型,枚举(enum)顾名思义就是⼀⼀列举。把可能的取值⼀⼀列举。
2.1枚举类型的例举:
例如:
一周的星期⼀到星期日是有限的7天,可以一一列举
 //星期
enum Weekday 
{  
    Sunday,  
    Monday,  
    Tuesday,  
    Wednesday,  
    Thursday,  
    Friday,  
    Saturday  
}; 
性别有:男、女、保密,也可以一一列举
//性别
enum Sex 
{  
    Male,  
    Female,  
    Cfidntl  
}; 
2.2枚举类型的优点
1. 增加代码的可读性和可维护性
2. 和#define定义的标识符⽐较枚举有类型检查,更加严谨。
3. 便于调试,预处理阶段会删除 #define 定义的符号
4. 使方便便,一次可以定义多个常量
5. 枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用
2.3 枚举类型的使用
#include <stdio.h>  
  
 
enum Color 
{  
    Red,  
    Green,  
    Blue,     
};  
  
int main()
 {  
    // 声明一个Color类型的变量  
    enum Color myColor;  
  
  
    myColor = Red;  
    switch (myColor) {  
        case Red:  
            printf("颜色是红色。\n");  
            break;  
        case Green:  
            printf("颜色是绿色。\n");  
            break;  
        case Blue:  
            printf("颜色是蓝色。\n");  
            break;  
        default:  
            printf("未知的颜色。\n");  
            break;  
    }  
      
    return 0;  
} 
注意,在C语言中,枚举常量默认从0开始,并且每个后续常量比前一个常量大1。因此,在这个例子中,Red的值为0,Green的值为1,Blue的值为2
当然也以拿整数给枚举变量赋值。在C语⾔中是可以的,但是在C++是不行的,C++的类型检查⽐ 较严格。
代码示例:
enum Color 
{  
    Red = 1,  
    Green = 2,  
    Blue = 3  
}; 
                









![CTF例题:[SWPU2019]Web1(无列名注入)](https://img-blog.csdnimg.cn/direct/e01b57540127493a807b7f868adacb25.png)





![【Linux】-Linux的实用操作:快捷键与软件安装操作、构建软连接、日期时区的设置[4]](https://img-blog.csdnimg.cn/direct/7654e33cac074abc994fff5b95c8fd8d.png)


