C 语言中的嵌套结构
什么是 C 语言中的嵌套结构?
在 C 语言中,结构体中的结构称为嵌套结构。如果结构体类型定义中的元素属于另一个结构体类型,则在 C 语言中我们称之为嵌套结构。如果结构体类型的元素本身是一个或多个类型的复合表示,则定义嵌套结构。
嵌套结构声明
嵌套结构可以通过将一个结构体作为另一个结构体的成员来声明。
语法
嵌套结构的一般语法如下:
struct struct1{ type var1; type var2; struct struct2 strvar; }
示例
我们可以在以下情况下考虑嵌套结构。假设我们要定义一个结构体类型,表示"学生",其元素为"姓名"和"年龄",以及另一个结构体类型"课程",其特征为"课程 ID"、"标题"和"学分"。此处,"学生"结构体内部包含一个课程结构体。
struct student{ char *name; int age; struct course c1; };
"学生"变量将按如下方式存储在内存中 -
Name | Age | Course | ||
---|---|---|---|---|
Kiran | 25 | 001 | C Programming | 6 |
访问嵌套结构的成员
可以使用点 (.) 运算符访问结构的成员。对于嵌套结构,可以存在多层结构。因此,您需要对结构的每一层使用点 (.) 运算符来访问嵌套结构的成员。
语法
以下是访问嵌套结构成员的语法 –
level1.level2.member_name;
此处,level1 表示外部(父)结构的结构变量,level2 表示内部(子)结构的结构变量。
示例
考虑以下嵌套结构定义 –
struct employee{ char name[10]; float salary; struct dob{ int d, m, y; } d1; }e1;
此处,e1 是外部(第一层)结构体"employee"的结构体变量,d1 是内部(第二层)结构体"dob"的结构体变量。
要访问 employee 结构体的成员,请使用 e1.member_name。
printf("Name: %s ", e1.name); printf("Salary: %f ", e1.salary);
要访问 dob 结构的成员,请使用 e1.d1.member_name。
printf("Date of Birth: %d-%d-%d ", e1.d1.d, e1.d1.m, e1.d1.y);
结构体的嵌套可以通过两种不同的方式实现 -
- 定义内联结构体
- 包含已定义结构体的元素
让我们通过合适的示例来学习这些方法。
通过定义内联结构体实现嵌套结构体
在此方法中,我们将定义一个"employee"数据类型,其元素之一是"出生日期"。C 语言没有"date"的内置类型。我们将在"employee"结构体内部声明一个"dob"结构体,其中包含三个"int"类型"d"、"m"和"y",其变量"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 ", e1.name); printf("Salary: %f ", e1.salary); printf("Date of Birth: %d-%d-%d ", 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 ", e1.name); printf("Salary: %f ", e1.salary); printf("Date of Birth: %d-%d-%d ", 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"包含一个"experiment"结构体类型的变量元素。反过来,experiment结构体包含两个"date"结构体类型的元素。
因此,"employee"变量的内存分配可以通过以下示例来理解 -
Name | Salary | Designation | from | to | ||||
---|---|---|---|---|---|---|---|---|
Kiran | 25000 | Clerk | 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 ", e1.name); printf("Salary: %f ", e1.salary); printf("Experience: Designation: %s ", e1.exp.designation); printf("From: %d-%d-%d ", e1.exp.from.d,e1.exp.from.m, e1.exp.from.y); printf("To: %d-%d-%d ", 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 ", ptr -> name); printf("Salary: %f ", ptr -> salary); printf("Date of Birth: %d-%d-%d ", ptr -> d1.d, ptr -> d1.m, ptr -> d1.y); return 0; }
输出
运行此代码时,将产生以下输出 -
Name: Kiran Salary: 25000.000000 Date of Birth: 12-5-1990