一种自定义的复合数据类型
结构体的定义
typedef struct 结构体名//这是定义一个结构体类型
{
成员类型1 成员名1;
成员类型2 成员名2;
...
成员类型n 成员名n;
} 别名; //名字可以省略,但是分号不能
- 一般建议给结构体的别名首字母大写,使用Typedef关键字
- 可以与结构体配合实现匿名函数体(不写函数体名)
// typedef 会出复杂笔试题
// int num; // 声明变量 num 其类型为 int
// typedef int num; // 创建 int 类型的别名 num //这是定义一个结构体变量
// int (*arr)[4];// 数组指针
// typedef int (*arr)[4]; // int (*)[4] 类型别名为 arr
// int (*func)(int , int); // 函数指针
typedef int (*func)(int, int); // func是个类型别名特指 int (*)(int , int) 类型
int (*p)(int a, int b) = add;
printf("%d \n", p(100, 77));
// 结构体类型别名
func q = add;
printf("%d \n", q(11, 33));
结构体初始化
按照定义的顺序依次初始化,用逗号隔开
struct dog
{
// unsigned char color;
char name[20];
int age;
int weight;
};
struct dog mydog = { //只能顺序初始化,新增结构体成员后需要重新初始化
"name";
23;
24;
}
指定成员初始化
- 成员初始化顺序可以改变
- 可以只初始化一部分成员
- 结构体新增成员后初始化语句仍可用(可维护性强)
struct dog mydog2 = {
.age = 3;
. name = "旺财";
}
结构体成员的引用
- 结构体指针提供了一个特殊运算符 -> 等价于 (*s).
typedef struct //定义一个匿名,但别名为Student的结构体
{
char name[20];
int age;
int score;
} Student;
//用法1---------------------
Student tom = {
.name = "Tom",
.age = 18,
.score = 85};
tom.score = 95;
printf("%s \n", tom.name);
printf("%d \n", tom.age);
printf("%d \n", tom.score);
//用法2--------------------------
Student *s1 = malloc(sizeof(Student)); //一个堆结构体
s1->age = 22;
strcpy(s1->name, "Jecia");
s1->score = 62;
printf("%s \n", s1->name);
printf("%d \n", s1->age);
printf("%d \n", s1->score);
结构体数组
对于一个结构体数组而言,数组的每一个空间用来存放结构体的所有成员变量,可以通过数组索引和"."的方式用来为成员变量赋值
typedef struct
{
char *name;
int age;
int score;
} Student;
Student s_arr[10] = {
{
.age = 17,
.name = "小王",
.score = 80
}
};
//创建一个堆空间给指针Student结构体变量s_arr2,与数组用法大致相似
Student *s_arr2 = malloc(sizeof(Student) * 10);
s_arr2[0].name = "hello";
s_arr2[0].age = 18;
s_arr2[0].score = 88;
结构体的尺寸
C语言中结构体的尺寸(sizeof(struct))是掌握内存布局和性能优化的关键
- 结构体尺寸的构成
#include <stdio.h>
#include <stddef.h>
struct Example1 {
char a; // 1字节
int b; // 4字节
short c; // 2字节
};
int main() {
printf("直观想法:1 + 4 + 2 = 7字节\n");
printf("实际大小:%zu 字节\n", sizeof(struct Example1));
printf("(通常输出12字节!)\n");
return 0;
}
- 影响结构体尺寸的三大要素
- 数据对齐
- 对于上面的结构体Example
- 第一个char型的变量a的偏移量为0,大小为一
- 填充三个字节,使int对齐到4字节边界
- 第二个int型的变量b的偏移量为4,大小为4
- 无填充,占用4字节大小
- 第三个short类型的变量c的偏移量为8,大小为2
- 前面的char与int致使short在内存空间中偏移8,因为short的大小为2,需要填充2字节,使之为4的倍数
- 第一个char型的变量a的偏移量为0,大小为一
- 总计占用12字节的内存
- 对于上面的结构体Example
- 填充字节
- 填充字节不可见
- 成员顺序
- 成员的排布顺序会影响结构体占用内存空间的大小,因为在内存空间中以四个字节为一组,未满会被编译器填充废字节
- 数据对齐


更多可以参考下面的链接
https://longuan.top/2026/01/20/c语言入门-结构体的尺寸/↗:C语言入门 – 结构体结构体的大小必须是最大对齐值的倍数
最大对齐值是结构体中占用字节数最大的变量的占用字节数
例如:若结构体中存在一个double类型的变量,那么结构体的大小必须是8的倍数
共用体(union)
几个不同的变量公用同一段内存,同一时间只能确认使用某一个类型的数据
- 联合体中所有成员共享一段内存
- 联合体中最大的数据成员的大小就是联合体的大小
- 大小端序
- 大端序
- 高位存放在低字节
- 小端序
- 低位存放在低字节
- 大端序
枚举(enum)
一种用于声明一组命令的常量,当一个变量有几种可能的取值时,可以将他定义为枚举类型
enum DIRECTION //枚举的名字
{
UP, //常量的名字
DOWN,
LEFT,
RIGHT
};
可以用在switch中做为判断条件
// int direction = 0; // 0上 1下 2左 3右
enum DIRECTION d = RIGHT;
switch (d)
{
case UP:
printf("向上 \n");
break;
case DOWN:
printf("向下 \n");
break;
case LEFT:
printf("向左 \n");
break;
case RIGHT:
printf("向右 \n");
break;
default:
break;
}
如果枚举内的变量没有赋值,默认从0开始,然后往后递增.
外界访问枚举类型的数据成员可以直接访问
Comments 1 条评论
const修饰的指针,const在前不可修改值,但是能修改指针指向的地址。const在后,指针指向的地址不可修改,但是内存的值可以修改 ,前后都有的情况则值和指向地址均不能修改(consit 类型 * consit 变量名)