C语言 结构体、共用体、枚举知识点整理
三者都属于构造数据类型,是用户自己组合出来的数据类型,不是C语言内置基础类型(char/int/float等)。
一、结构体 struct
1. 声明语法
struct 结构体名
{
数据类型 成员名1;
数据类型 成员名2;
//更多成员
}; //分号不能省略
- 可以省略结构体名,得到匿名结构体,只能紧跟着定义变量,不能后续复用。
- 结构体内部可以嵌套别的结构体。
2. 定义变量
//方式1:先声明类型,再定义变量
struct Date
{
int year;
int mon;
int day;
};
struct Date d1;
//方式2:声明同时定义变量
struct Date
{
int year;
int mon;
int day;
}d2;
3. 初始化
//全部初始化
struct Date d1 = {2026,8,18};
//指定成员初始化(推荐)
struct Date d2 = {.year=2026,.day=18};
4. 成员访问
- 结构体变量 . 成员名:普通结构体变量访问
d1.year = 2026;
- 结构体指针 -> 成员名:结构体指针访问
struct Date *p = &d1;
p->year = 2026;
5. 内存存储(内存对齐)
- 每个成员存储在自身字节大小的整数倍地址。
- 结构体总大小 = 最大成员字节数的整数倍,中间会填充对齐字节。
- 可以用
#pragma pack(n)强制修改对齐字节。
#pragma pack(1) //按1字节对齐,关闭对齐
struct S{
int a;
char b;
};
#pragma pack() //恢复默认对齐
6. 函数传参
- 值传递:拷贝整个结构体,开销大,函数内修改不会影响外部原变量。
- 传地址(结构体指针):只传地址,效率高;函数内可以修改外部结构体成员。
7. 结构体数组
数组每个元素都是结构体类型,数组[下标].成员访问成员。
二、共用体(联合体) union
1. 声明语法
union 共用体名
{
数据类型 成员1;
数据类型 成员2;
};
2. 核心特点⭐
- 所有成员共享同一块内存空间,同一时刻只能有效使用其中一个成员。
- 共用体占用内存大小:等于占用字节最大的那个成员的大小。
- 存储结果取决于最后一次赋值的成员,给一个成员赋值会覆盖其他成员数据。
3. 变量定义、成员访问
和结构体语法完全一样:
- 变量访问:
union变量.成员 - 指针访问:
union指针->成员
4. 典型用途:判断系统大小端
union S{
int a;
char b;
};
union S tmp;
tmp.a = 1;
if(tmp.b){
printf("小端\n");
}else{
printf("大端\n");
}
小端:低地址存低字节;大端:低地址存高字节。
三、枚举 enum
1. 声明语法
enum 枚举名
{
枚举常量1,
枚举常量2,
枚举常量3
};
{}内部是整型枚举常量,不是变量,不能写数据类型。- 常量之间逗号分隔。
2. 枚举常量赋值规则
- 如果不给值:默认从0开始,后续依次+1
enum Color{RED,GREEN,BLUE};
// RED=0,GREEN=1,BLUE=2
- 指定某一个常量的值,后面常量自动递增1
enum Week{MON=1,TUE,WED,THU};
// MON=1,TUE=2,WED=3,THU=4
3. 枚举变量
enum Week w = MON;
枚举变量本质就是整型,可以直接和整数比较。
4. 使用规范
枚举常量习惯大写,区分普通变量。
四、typedef给构造类型重命名
typedef:给已有数据类型起别名,不是创造新类型
//结构体别名
typedef struct Student{
char name[32];
int score;
}STU_s;
//共用体别名
typedef union Data{
int i;
char c;
}DATA_u;
//枚举别名
typedef enum{
ON,OFF
}STATE_e;
//使用别名定义变量,不用写struct/union/enum
STU_s s1;
DATA_u d1;
STATE_e st;
五、struct / union / enum 异同对比
| 对比项 | 结构体 struct | 共用体 union | 枚举 enum |
|---|---|---|---|
| 作用 | 把多个不同含义的数据同时保存到一起 | 多个成员共享同一块内存,同一时刻只用一个成员 | 定义一组整型符号常量,增加代码可读性 |
| 内存大小 | 受内存对齐影响,≥所有成员字节总和 | 等于最大成员的字节大小 | 就是int大小,枚举本质是整型 |
| 成员内存关系 | 每个成员拥有独立内存空间 | 全部成员共用同一块内存空间 | 没有成员变量,全部是整型常量 |
| 赋值 | 所有成员可以同时保存有效数据 | 修改一个成员,覆盖其他成员的数据 | 只能给枚举变量赋值枚举常量,常量不能修改 |
| 典型场景 | 描述一个事物的多项属性(学生信息、时间) | 节省内存、大小端检测,多类型复用空间 | 状态标记、选项集合(开关、星期) |
相同点
- 三者都是构造类型,需要先声明类型,再定义变量;
- 都支持
typedef起别名; - 声明的时候
}后面必须带分号; - 都可以做函数参数、数组元素。
关键区别总结
- 结构体:成员互相独立,同时共存;
- 共用体:成员互相覆盖,互斥共存;
- 枚举:没有普通成员,只有一组整型符号常量。
补充易错点
- 结构体不要忘记最后的分号;
- union不要同时使用多个成员,只有最后赋值的成员有效;
- enum里面是常量,不能对枚举常量赋值;
- typedef只是别名,不是新类型;
- 结构体存在内存对齐,sizeof结果不等于成员简单相加。
struct、union、enum完整演示代码
#include <stdio.h>
//==================== 结构体 struct ====================
//声明结构体类型
struct Student
{
char name[32];
int age;
int score;
};
//typedef给结构体起别名
typedef struct Date
{
int year;
int mon;
int day;
}Date_s;
//结构体传参:传地址(推荐,效率高,可以修改外部变量)
void printStu(struct Student *p)
{
printf("姓名:%s 年龄:%d 分数:%d\n", p->name, p->age, p->score);
p->score = 99; //修改外部结构体成员
}
//==================== 共用体 union ====================
union Data
{
int i;
char c;
float f;
};
//大小端检测共用体
typedef union EndianTest
{
int a;
char b;
}Endian_u;
//==================== 枚举 enum ====================
//枚举,默认从0开始
enum Color
{
RED,
GREEN,
BLUE
};
//手动指定枚举起始值
typedef enum Week
{
MON = 1,
TUE,
WED,
THU,
FRI,
SAT,
SUN
}Week_e;
int main(void)
{
//---------- 结构体使用 ----------
struct Student s1 = {"zhangsan", 18, 88};
printStu(&s1);
printf("修改后分数:%d\n", s1.score);
//指定成员初始化
Date_s d1 = {.year = 2026, .day = 18};
printf("date:%d年%d月%d日\n", d1.year, d1.mon, d1.day);
printf("结构体Student大小:%zu\n\n", sizeof(struct Student));
//---------- 共用体使用 ----------
union Data u1;
u1.i = 100;
printf("u1.i = %d\n", u1.i);
u1.c = 'A'; //给c赋值,会覆盖i的数据
printf("u1.c = %c , u1.i = %d\n", u1.c, u1.i);
printf("共用体Data大小:%zu\n\n", sizeof(union Data));
//大小端测试
Endian_u et;
et.a = 1;
if(et.b == 1)
{
printf("本机:小端模式\n");
}
else
{
printf("本机:大端模式\n\n");
}
//---------- 枚举使用 ----------
enum Color c = RED;
printf("RED=%d GREEN=%d BLUE=%d\n", RED, GREEN, BLUE);
Week_e w = WED;
printf("WED = %d\n", w);
if(w == WED)
{
printf("今天是周三\n");
}
return 0;
}
编译运行
gcc test.c -o a.out
./a.out
输出示例(小端机器)
姓名:zhangsan 年龄:18 分数:88
修改后分数:99
date:2026年0月18日
结构体Student大小:40
u1.i = 100
u1.c = A , u1.i = 65
共用体Data大小:4
本机:小端模式
RED=0 GREEN=1 BLUE=2
WED = 3
今天是周三
重点代码说明
- 结构体
结构体指针->成员,普通变量用.访问成员;- 传指针可以修改外部原始结构体;值传递会拷贝一份,修改不会影响外部。
- 共用体>
所有成员共用一块内存,对一个成员赋值,其他成员数据被覆盖。
u1.i = 100;
u1.c = 'A'; //覆盖上面i的值
- 枚举
- 枚举里面
RED,GREEN是常量,不能写RED=100;; - 枚举变量本质就是int,可以直接做判断、比较。
- typedef
typedef 原类型 别名,只是起别名,没有创造新的数据类型。

348

被折叠的 条评论
为什么被折叠?



