自定义类型-结构体(一)
自定义类型
是程序员根据需求自己定义的数据类型,用于更灵活地组织和管理数据
C语言自带的类型无法描述一些复杂的对象
这时引用的自定义类型来进行描述
自定义类型具有:结果体,联合体,枚举三中自定义类型
特性 | 基础类型 | 自定义类型 |
---|---|---|
定义 | 语言内置(如int 、char ) | 程序员自行定义(如struct 、enum ) |
复杂度 | 单一值 | 可包含多个成员或逻辑关系 |
内存占用 | 固定大小(如int 占4字节) | 由成员决定(如结构体各成员之和) |
用途 | 存储简单数据 | 表示复杂数据或业务逻辑 |
结构体
结构体的定义
结构体定义的本质是创建一个新类型和描述该类型具有的属性
struct [结构体名称] {数据类型 成员名;数据类型 成员名; 成员声明的语法:数据类型 成员名// ... 更多成员
} [变量名]; 变量名表示创建了一个该类型的变量,也可以不在末尾创建变量,在后续过程中进行创建结构体的定义,只单纯的描述这个类型具有的属性有哪些,并不能直接使用需要创建变量对变量进行初始化才能使用该类型
// 定义结构体类型
struct Student {char name[20];int age;float score;
} stu1,stu2; stu1,stu2表述创建了两个名为stu1,stu2的struct Student类型的变量
匿名结构体
是指在定义结构体时不指定结构体标签(没有结构体名称)
struct {数据类型 成员名;数据类型 成员名; // ... 更多成员
} [变量名];
匿名结构体的定义,在末尾必须定义至少一个变量
否则后续将因为没有类型而无法使用
结构体的初始化
顺序初始化
struct Student {char name[20];int age;float score;
}; 按照结构体定义的成员变量的顺序进行定义
struct Student stu1 = {"Alice", 20, 95.5}; 直接访问指定初始化
方法1
struct Student stu2 = {.age = 22,.name = "Bob", 在进行指定初始化时,必须使用点操作符.score = 88.0 成员变量后接的是 逗号 而不是 分号
};
方法2
struct Student stu1 = {age = 22,name = "Bob",score = 88.0};
当结构体内嵌套一个结构体时
struct Student { 内层结构体int age;float score;
};
struct Student stu2 = { 外层结构体int age;char name;struct Student a;};
int main ()
{ 嵌套访问struct Student stu2 b ={ 20,"李明",{ 19 , 70 } };
} 对嵌套在结构体内的结构体初始化时,要在花括号内在开一个花括号对嵌套在内的结构体的成员变量逐一初始化
匿名结构体初始化
匿名结构体必须在定义时直接声明变量并初始化,否则无法在后续代码中使用
// 定义匿名结构体并初始化变量 point
struct { int x; int y;
} point = {10, 20}; // 顺序初始化// 指定成员初始化(C99+)
struct { int width; int height;
} rect = { .width = 100, .height = 200
};
特性 | 匿名结构体 | 普通结构体 |
---|---|---|
类型名 | 无(无法复用类型) | 有(通过 struct 标签名 或 typedef 别名复用) |
变量声明时机 | 必须在定义时声明变量 | 可后续声明变量(如 struct Point p; ) |
嵌套初始化语法 | 可直接访问成员,无需外层结构体名(见示例) | 需通过外层结构体名访问(如 outer.inner.x ) |
动态初始化 | 只能通过复合字面量或指针间接实现 | 可直接声明变量后赋值或动态分配内存 |
代码复用性 | 低(单次使用) | 高(可多次声明变量) |
结构成员访问
结构体成员的访问是通过点操作符( . )来完成的
匿名结构体的访问与普通结构体访问的方式一致
直接访问
struct p { int x;int y;
};
printf("x %d y %d\n", p.x, p.y)在printf中p表示要访问的结构体的名称点操作符后面的内容表示要访问的成员变量
嵌套访问
struct Student { 内层结构体int age;float score;
};
struct Student stu2 = { 外层结构体int age;char name;struct Student a;};
int main ()
{ 嵌套访问struct Student stu2 b ={ 20,"李明",{ 19 , 70 } };
}
指针访问结构体
struct Book {char title[50]; 定义书的结构体float price;
};int main() { // 通过指针访问成员strcpy(book->title, "C Programming"); 语法:结构体标识名->要初始化的成员变量 ,初始化的值book->price = 99.9;}
场景 | 匿名结构体 | 普通结构体 |
---|---|---|
直接访问成员 | 变量名.成员 | 变量名.成员 |
嵌套访问成员 | 直接通过外层变量访问:外层变量.成员 | 需通过中间结构体名:外层变量.内层变量.成员 |
指针访问成员 | 指针->成员 | 指针->成员 |
动态分配后访问 | 与普通结构体一致 | 与匿名结构体一致 |
结构体的自引用
是指一个结构体(
struct
)内部包含一个指向 自身类型的指针。这种特性常用于实现链表、树、图等动态数据结构
struct Node {int data; 数据域struct Node* next; 自引用:指向同类型的指针
}; struct Node* next 表示 next 是一个指向 struct Node 类型的指针