结构体
概念
- 定义:结构体(structure)是C语言中一种重要的数据类型,它允许你将不同类型的数据组合在一起作为一个整体来处理。
struct 结构体名称 {
数据类型 成员名1;
数据类型 成员名2;
// 其他成员
};
- 构造类型:自定义数据类型。是由一批不同类型的数据组合而成的一种新的数据类型。
- 构造类型是数据类型,所以在使用的时候不可以单独使用,而是必须申请一个变量,通过变量操作构造类型的内存空间。
- 组成构造类型的每一个部分,称之为:成员
格式
- 结构体定义位置一般放在头文件下方,或者头文件中。
- 用关键字struct表示结构体。
- 无名结构体(Anonymous Struct),又称为匿名结构体,是一种在定义结构体时不指定结构体名称的用法。这种结构体不能直接通过名称来声明变量或创建实例,但可以作为其他结构体、共用体(union)或数组的成员。
struct {
char name[50];
int age;
float score;
} student;//student1是一个无名结构体变量,结构体本身没有名称,但可以通过student来访问它的成员
//由于无名结构体没有名字,所以只能在声明结构体类型后立即申请变量,可以多申请几个,在student后面加上即可
-------------------------------------------------------范例
#include <stdio.h>
#include <string.h>
// 定义带有无名结构体成员的结构体
struct Student {
char name[50];
int age;
struct {
int day;
int month;
int year;
} birthdate; // 无名结构体
};
int main() {
// 创建结构体变量
struct Student student1;
// 设置成员的值
strcpy(student1.name, "Alice");
student1.age = 20;
student1.birthdate.day = 15;
student1.birthdate.month = 8;
student1.birthdate.year = 2000;
// 输出成员的值
printf("Name: %s\n", student1.name);
printf("Age: %d\n", student1.age);
printf("Birthdate: %02d/%02d/%04d\n",
student1.birthdate.day,
student1.birthdate.month,
student1.birthdate.year);
return 0;
}
- 有名结构体
--------------定义格式
struct 结构体名
{
成员类型 成员名1;
成员类型 成员名2;
成员类型 成员名3;
};//也可以加上变量,不过因为是在头文件下面,申请的是全局结构体变量
struct 结构体名 变量名1,变量名2;//strcut node x1,*x2;
- typedef 旧的类型名 新的数据类型名1,新的数据类型名2
typedef int INT,PINT;//实际上是将int取了两个别名
typedef int* IM;//将int*改名为IM
- 无名结构体重命名
typedef struct{
成员类型 成员名1;
成员类型 成员名2;
成员类型 成员名3;
}Node,NODE;//此时Node,NODE不再是数据变量名了,而是该结构体的类型名,效果等同于Node a;这个时候a是一个结构体变量。
- 有名结构体重命名
typedef struct element{
char name[50];
int age;
float gpa;
} Student;//此时struct element的效果等价于Student,都是结构体类型名
-
结构体变量初始化
-
结构体成员访问
- 结构体普通变量用:用"."访问。结构体的普通变量名.成员名。
- 结构体指针变量:用"->"访问。结构体的指针变量名->成员名。
- 用printf打印东西过多时,可以先使用“\”后面再跟上换行符即可。
-
结构体大小的计算
- 用sizeof计算
- 结构体对齐
- 基本对齐:每个数据类型都有一个对齐要求(alignment requirement),通常是该数据类型大小的整数倍。例如,int通常要求4字节对齐,double通常要求8字节对齐。
- 结构体对齐:结构体的总大小也必须是其最大对齐要求的整数倍,但是最大为操作系统一次所取的字节数,这样可以保证数组中每个结构体实例都按照其最大成员的对齐要求对齐。
- 不同的操作系统一次默认取的字节数不同,即操作系统默认对齐系数不同
64位OS默认:8个字节取一次
b.32位OS默认:4个字节取一次 - 成员的自身对齐系数 = 操作系统默认对齐系数 < 成员的自身对齐值?操作系统默认对齐系数:成员所占字节数
- 用sizeof计算
-
嵌套结构体的大小:结构体的对齐值为–》结构体中成员最大的对齐值。
-
改变对齐方式
可以使用#pragma pack指令来改变默认的对齐方式。
#pragma pack(value) value=2^n次方(n=0,1,2,3,4) value=1 2 4 8 16 32
但是64为操作系统最多只能处理8个字节的数据,所以将默认对齐值设置为超过8,不生效
#pragma pack() //重置编译器的默认对齐值 -
取消结构体对齐
使用: __attribute__((packed))取消结构体对齐
typedef struct
{
char a;
short b;
int c;
}__attribute__((packed)) _t1
//取消结构体对齐,在编译过程中按照实际占用的字节数进行申请内存。
联合体
- 共用体(union)是C语言中的一种数据结构,它允许多个成员共享同一块内存。与结构体(struct)不同,共用体中的所有成员从相同的内存地址开始,因此共用体的大小等于其中最大成员的大小。
- 定义
union Example {
int i;
float f;
char c;
};//可以像访问结构体成员一样访问共用体成员,但是同一时间只能使用一个成员,定义的结构类似于结构体
枚举类型
- 枚举类型(enum)是一种用户定义的类型,它允许为一组整型常量指定符号名称。这使得代码更具可读性和可维护性。枚举类型定义使用关键字enum。
- 每个常量都隐式地被赋予一个整型值,从0开始递增。也可以显式地指定常量的值。
- 可以显式地指定枚举常量的值,并且后续常量的值会基于显式指定的值递增。
enum Weekday {
MONDAY = 1,
TUESDAY, // 2
WEDNESDAY, // 3
THURSDAY = 10,
FRIDAY, // 11
SATURDAY, // 12
SUNDAY // 13
};
- 枚举类型是一种强大的工具,可以提高代码的可读性和可维护性。