- C编程教程
- C - 首页
- C语言基础
- C - 概述
- C - 特性
- C - 历史
- C - 环境设置
- C - 程序结构
- C - Hello World
- C - 编译过程
- C - 注释
- C - 词法单元
- C - 关键字
- C - 标识符
- C - 用户输入
- C - 基本语法
- C - 数据类型
- C - 变量
- C - 整数提升
- C - 类型转换
- C - 类型强制转换
- C - 布尔值
- C语言中的常量和字面量
- C - 常量
- C - 字面量
- C - 转义序列
- C - 格式说明符
- C语言中的运算符
- C - 运算符
- C - 算术运算符
- C - 关系运算符
- C - 逻辑运算符
- C - 位运算符
- C - 赋值运算符
- C - 一元运算符
- C - 自增和自减运算符
- C - 三元运算符
- C - sizeof 运算符
- C - 运算符优先级
- C - 其他运算符
- C语言中的决策
- C - 决策
- C - if 语句
- C - if...else 语句
- C - 嵌套 if 语句
- C - switch 语句
- C - 嵌套 switch 语句
- C语言中的循环
- C - 循环
- C - while 循环
- C - for 循环
- C - do...while 循环
- C - 嵌套循环
- C - 无限循环
- C - break 语句
- C - continue 语句
- C - goto 语句
- C语言中的函数
- C - 函数
- C - 主函数
- C - 按值调用函数
- C - 按引用调用函数
- C - 嵌套函数
- C - 可变参数函数
- C - 用户自定义函数
- C - 回调函数
- C - return 语句
- C - 递归
- C语言中的作用域规则
- C - 作用域规则
- C - 静态变量
- C - 全局变量
- C语言中的数组
- C - 数组
- C - 数组的特性
- C - 多维数组
- C - 将数组传递给函数
- C - 从函数返回数组
- C - 可变长数组
- C语言中的指针
- C - 指针
- C - 指针和数组
- C - 指针的应用
- C - 指针运算
- C - 指针数组
- C - 指向指针的指针
- C - 将指针传递给函数
- C - 从函数返回指针
- C - 函数指针
- C - 指向数组的指针
- C - 指向结构体的指针
- C - 指针链
- C - 指针与数组
- C - 字符指针和函数
- C - 空指针
- C - void 指针
- C - 悬空指针
- C - 解引用指针
- C - 近、远和巨型指针
- C - 指针数组的初始化
- C - 指针与多维数组
- C语言中的字符串
- C - 字符串
- C - 字符串数组
- C - 特殊字符
- C语言中的结构体和联合体
- C - 结构体
- C - 结构体和函数
- C - 结构体数组
- C - 自引用结构体
- C - 查找表
- C - 点 (.) 运算符
- C - 枚举 (或 enum)
- C - 结构体填充和打包
- C - 嵌套结构体
- C - 匿名结构体和联合体
- C - 联合体
- C - 位段
- C - typedef
- C语言中的文件处理
- C - 输入和输出
- C - 文件 I/O (文件处理)
- C 预处理器
- C - 预处理器
- C - 指令
- C - 预处理器运算符
- C - 宏
- C - 头文件
- C语言中的内存管理
- C - 内存管理
- C - 内存地址
- C - 存储类别
- 其他主题
- C - 错误处理
- C - 可变参数
- C - 命令执行
- C - 数学函数
- C - static 关键字
- C - 随机数生成
- C - 命令行参数
- C编程资源
- C - 问答
- C - 快速指南
- C - 速查表
- C - 有用资源
- C - 讨论
C语言中的嵌套结构体
什么是C语言中的嵌套结构体?
结构体内部的结构体称为**C语言中的嵌套结构体**。当结构体定义中的某个元素是另一个结构体类型时,我们就称之为 C 语言中的嵌套结构体。当结构体类型中的某个元素本身是另一种或多种类型组合的表示时,就会定义嵌套结构体。
嵌套结构体声明
可以通过使用结构体作为另一个结构体的成员来声明嵌套结构体。
语法
嵌套结构体的通用语法如下:
struct struct1{ type var1; type var2; struct struct2 strvar; }
示例
我们可以在以下情况下考虑嵌套结构体。如果我们想定义一个表示“学生”的结构体类型,其中包含“姓名”和“年龄”作为其元素,以及另一个名为“课程”的结构体类型,其特征是“课程 ID”、“标题”和“学分”。这里,“学生”结构体包含一个内部的“课程”结构体。
struct student{ char *name; int age; struct course c1; };
“学生”变量将在内存中存储如下:
姓名 | 年龄 | 课程 | ||
---|---|---|---|---|
Kiran | 25 | 001 | C编程 | 6 |
访问嵌套结构体的成员
可以使用点 (.) 运算符访问结构体的成员。在嵌套结构体的情况下,可能存在多个级别的结构体。因此,您需要对每个级别的结构体使用点 (.) 运算符来访问嵌套结构体的成员。
语法
以下是访问嵌套结构体成员的语法:
level1.level2.member_name;
这里,level1表示外部(父)结构体的结构体变量,而level2表示内部(子)结构体的结构体变量。
示例
考虑以下嵌套结构体定义:
struct employee{ char name[10]; float salary; struct dob{ int d, m, y; } d1; }e1;
这里,e1是外部(第 1 级)结构体“employee”的结构体变量,而d1是内部(第 2 级)结构体“dob”的结构体变量。
要访问employee结构体的成员,请使用e1.member_name。
printf("Name: %s\n", e1.name); printf("Salary: %f\n", e1.salary);
要访问dob结构体的成员,请使用e1.d1.member_name。
printf("Date of Birth: %d-%d-%d\n", e1.d1.d, e1.d1.m, e1.d1.y);
嵌套结构体可以通过两种不同的方式执行:
- 定义内联结构体
- 包含已定义的结构体的元素
让我们使用合适的示例来学习这些方法。
通过定义内联结构体进行嵌套结构体
在这种方法中,我们将定义一个“员工”数据类型,其元素之一为“出生日期”。C 语言没有内置的“日期”类型。我们将在“员工”结构体内部声明一个包含三个“int”类型“d”、“m”和“y”的“dob”结构体,其变量“d1”是外部类型的元素之一。
示例
请看下面的例子:
#include <stdio.h> #include <string.h> struct employee{ char name[10]; float salary; struct dob{ int d, m, y; } d1; }; int main(){ struct employee e1 = {"Kiran", 25000, {12, 5, 1990}}; printf("Name: %s\n", e1.name); printf("Salary: %f\n", e1.salary); printf("Date of Birth: %d-%d-%d\n", e1.d1.d, e1.d1.m, e1.d1.y); return 0; }
输出
运行此代码时,将产生以下输出:
Name: Kiran Salary: 25000.000000 Date of Birth: 12-5-1990
您可以看到“employee”类型的变量初始化时,其“date”元素使用了另一对花括号。
通过定义单独的结构体进行嵌套结构体
使用嵌套结构体的另一种方法是首先定义内部结构体类型,然后使用其变量作为外部结构体类型中的元素之一,该外部结构体类型随后定义。
这里,“dob”类型在开头定义;它有三个“int”元素:d、m和y。“employee”结构体类型随后定义。
示例 1
由于“dob”已经定义,因此我们可以在“employee”中包含其类型的一个元素。
#include <stdio.h> #include <string.h> struct dob{ int d, m, y; }; struct employee{ char name[10]; float salary; struct dob d1; }; int main(){ struct employee e1 = {"Kiran", 25000, {12, 5, 1990}}; printf("Name: %s\n", e1.name); printf("Salary: %f\n", e1.salary); printf("Date of Birth: %d-%d-%d\n", e1.d1.d, e1.d1.m, e1.d1.y); return 0; }
输出
运行代码并检查其输出:
Name: Kiran Salary: 25000.000000 Date of Birth: 12-5-1990
请注意,内部结构体类型应在外部类型之前定义。我们还可以声明“dob”类型的变量,然后将其包含在“employee”类型变量的初始化中,如下所示:
struct dob d1 = {12, 5, 1990}; struct employee e1 = {"Kiran", 25000, d1};
示例 2
在以下代码中,结构体的嵌套达到了两级。换句话说,外部结构体类型“employee”有一个元素,它是“experience”结构体类型的一个变量。反过来,“experience”结构体有两个元素,它们是另一个名为“date”的结构体类型。
因此,可以根据以下图示理解“employee”变量的内存分配:
姓名 | 薪资 | 职位 | 从 | 到 | ||||
---|---|---|---|---|---|---|---|---|
Kiran | 25000 | 职员 | 12 | 5 | 1990 | 31 | 3 | 2021 |
以下是完整代码:
#include <stdio.h> #include <string.h> struct date{ int d, m, y; }; struct experience{ char designation[10]; struct date from; struct date to; }; struct employee{ char name[10]; float salary; struct experience exp; }; int main(){ struct date d1 = {12, 5, 1990}; struct date d2 = {31, 3, 2021}; struct experience exp = {"Clerk", d1, d2}; struct employee e1 = {"Kiran", 25000, exp}; printf("Name: %s\n", e1.name); printf("Salary: %f\n", e1.salary); printf("Experience: Designation: %s\n", e1.exp.designation); printf("From: %d-%d-%d\n", e1.exp.from.d,e1.exp.from.m, e1.exp.from.y); printf("To: %d-%d-%d\n", e1.exp.to.d, e1.exp.to.m, e1.exp.to.y ); return 0; }
输出
运行此代码时,将产生以下输出:
Name: Kiran Salary: 25000.000000 Experience: Designation: Clerk From: 12-5-1990 To: 31-3-2021
指向嵌套结构体的指针
我们知道,结构体变量的地址可以存储在指针变量中。此外,C 语言使用间接运算符 (→) 来访问指针引用的变量的元素。
在嵌套结构体的情况下,内部结构体元素的元素通过“ptr → inner_struct_var.element;”访问。
示例
在此示例中,我们声明了一个指向 employee 结构体变量的指针 ptr。内部 dob 结构体变量的 date、month 和 year 元素分别通过“ptr -> d1.d”、“ptr -> d1.m”和“ptr -> d1.y”表达式访问。
#include <stdio.h> #include <string.h> struct employee{ char name[10]; float salary; struct dob{ int d, m, y; } d1; }; int main(){ struct employee e1 = {"Kiran", 25000, {12, 5, 1990}}; struct employee *ptr = &e1; printf("Name: %s\n", ptr -> name); printf("Salary: %f\n", ptr -> salary); printf("Date of Birth: %d-%d-%d\n", ptr -> d1.d, ptr -> d1.m, ptr -> d1.y); return 0; }
输出
运行此代码时,将产生以下输出:
Name: Kiran Salary: 25000.000000 Date of Birth: 12-5-1990