Cprogramming 简明教程

Nested Structures in C

What is a Nested Structure in C?

结构体中的 structure 称为 nested structure in C 。当结构体类型的某个元素是另一个结构体类型时,我们称之为 C 中的嵌套结构体。当结构体类型的一个元素本身是表示一个或多个类型的复合表示形式时,就会定义嵌套结构体。

A structure within a structure is known as nested structure in C. When one of the elements in the definition of a struct type is of another struct type, then we call it a nested structure in C. Nested structures are defined when one of the elements of a struct type is itself a composite representation of one or more types.

Nested Structure Declaration

可以通过将结构体用作另一个结构体的成员来声明嵌套结构体。

A nested structure can be declared by using a structure as a member of another structure.

Syntax

嵌套结构体的通用语法如下 −

A general syntax of a nested structure is as follows −

struct struct1{
   type var1;
   type var2;
   struct struct2 strvar;
}

Example

我们可以在以下情况下考虑嵌套结构体。如果我们想要定义一个表示“学生”的结构体类型,它的元素是“姓名”和“年龄”,而另一个称为“课程”的结构体类型则以“课程 ID”、“标题”和“学分”为特征。这里,“学生”结构体有一个内部课程结构。

We can think of nested structures in the following situation. If we want to define a struct type representing a "student" with "name" and "age" as its elements and another struct type called "course" that is characterized by "course ID", "title", and "credit points". Here, the "student" structure has an inner course structure.

struct student{
   char *name;
   int age;
   struct course c1;
};

“学生”变量将按如下方式存储在内存中 −

The "student" variable will be stored in the memory as follows −

Name

Age

Course

Kiran

25

001

Accessing Members of a Nested Structure

可以使用 dot (.) operator 访问结构体的成员。对于嵌套结构体,可以有多个结构体级别。因此,您需要为每个结构体级别使用点 (.) 运算符来访问嵌套结构体的成员。

The structure’s members can be accessed by using the dot (.) operator. In the case of nested structures, there can be multiple levels of structures. So, you need to use the dot (.) operator for each level of the structure to access the members of the nested structure.

Syntax

以下是访问嵌套结构体的成员的语法 −

Below is the syntax to access members of nested structure –

level1.level2.member_name;

此处,level1 表示外部(父)结构体的结构体变量,level2 表示内部(子)结构体的结构体变量。

Here, level1 represents the structure variable of the outer (parent) structure, and level2 represents the structure variable of the inner (child) structure.

Example

考虑以下嵌套结构体定义 −

Consider the following nested structure definition –

struct employee{
   char name[10];
   float salary;
   struct dob{
      int d, m, y;
   } d1;
}e1;

此处,e1 是外部(level 1)结构体“employee” 的结构体变量,d1 是内部(level 2)结构体“dob” 的结构体变量。

Here, e1 is the structure variable of the outer (level 1) structure "employee" and d1 is the structure variable of the inner (level 2) structure "dob".

要访问 employee 结构体的成员,请使用 e1.member_name。

To access the members of the employee structure, use e1.member_name.

printf("Name: %s\n", e1.name);
printf("Salary: %f\n", e1.salary);

要访问 dob 结构的成员,请使用 e1.d1.member_name。

To access the members of the dob structure, use e1.d1.member_name.

printf("Date of Birth: %d-%d-%d\n", e1.d1.d, e1.d1.m, e1.d1.y);

结构的嵌套可以用两种不同的方式执行 −

The nesting of structures can be performed in two different ways −

  1. Defining an inline structure

  2. Including the element of a structure already defined

我们使用合适的示例学习这些方法。

Let us learn these methods using suitable examples.

Nested Structure by Defining Inline Structure

在此方法中,我们将定义“employee”数据类型,其中一个元素是“出生日期”。C 没有“date”的内置类型。我们将在“employee”结构中声明带有三个“int”类型“d”、“m”和“y”的“dob”结构,其变量“d1”是外部类型之一。

In this method, we shall define an "employee" data type with one of its elements being "date of birth". C doesn’t have a built-in type for "date". We shall declare the "dob" struct with three "int" types "d", "m" and "y" inside the "employee" structure and its variable "d1" is one of the elements of the outer type.

Example

请看以下示例:

Take a look at the following example −

#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;
}

当你运行这段代码时,它将产生以下输出:

When you run this code, it will produce the following output −

Name: Kiran
Salary: 25000.000000
Date of Birth: 12-5-1990

你可以看到,类型为“employee”的变量使用带有另一对大括号的“date”元素进行了初始化。

You can see that the variable of "employee" type is initialized with its "date" element having another pair of curly brackets.

Nested Structure by Defining Separate Structure

使用嵌套结构的另一种方法是先定义内部结构类型,然后使用其变量作为外部结构类型中的元素之一,该结构类型是在内部结构类型之后定义的。

The other approach for using nested structures is to define the inner struct type first, and then use its variable as one of the elements in the outer struct type, which is defined afterwards.

在此,“dob”类型在开头定义;它有三个“int”元素 − dmy 。“employee”结构类型在之后定义。

Here, the "dob" type is defined in the beginning; it has three "int" elements − d, m and y. The "employee" struct type is defined afterwards.

Example 1

由于“dob”已定义,因此我们可以在“employee”内部拥有其类型的元素。

Since "dob" is already defined, we can have an element of its type inside "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;
}

运行代码并检查其输出:

Run the code and check its output −

Name: Kiran
Salary: 25000.000000
Date of Birth: 12-5-1990

请注意,内部结构类型应该在外部类型之前定义。我们还可以声明一个“dob”类型变量,然后将其包含在“employee”类型变量的初始化中,如下所示:

Note that the inner struct type should be defined before the outer type. We can also declare a variable of "dob" type and then include it in the initialization of "employee" type variable, as shown below −

struct dob d1 = {12, 5, 1990};
struct employee e1 = {"Kiran", 25000, d1};

Example 2

在下面的代码中,结构的嵌套达到两个级别。换句话说,外部结构类型“employee”有一个元素是经验结构类型的变量。反过来,经验结构有另一个称为“date”的结构类型的两个元素。

In the following code, the nesting of structure goes upto two levels. In other words, the outer struct type "employee" has one element that is a variable of experience struct type. In turn, the experience structure has two elements of another struct type called "date".

因此,“employee”变量的内存分配可以通过以下示例说明:

Hence, the memory allocation for "employee" variable can be understood with the following illustration −

Name

Salary

Designation

from

to

Kiran

25000

Clerk

12

5

以下是完整代码——

Here is the complete code −

#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;
}

当你运行这段代码时,它将产生以下输出:

When you run this code, it will produce the following output −

Name: Kiran
Salary: 25000.000000
Experience: Designation: Clerk
From:  12-5-1990
To: 31-3-2021

Pointer to Nested Structure

我们知道,可以将结构变量的地址存储在 pointer variable 中。此外,C 使用间接运算符 (→) 来访问指针引用的变量的元素。

We know that the address of a struct variable can be stored in a pointer variable. Further, C uses the indirection operator (→) to access the elements of a variable that is referenced by a pointer.

对于嵌套结构,内部结构元素的元素通过“ptr → inner_struct_var.element;”来访问

In case of a nested structure, the elements of the inner struct elements are accessed by "ptr → inner_struct_var.element;"

Example

在此示例中,我们已将指针 ptr 声明为指向 employee 结构变量。内部 dob 结构变量的日期、月份和年份元素分别访问为“ptr → d1.d”、“ptr → d1.m”和“ptr → d1.y”表达式。

In this example, we have declared a pointer ptr to an employee struct variable. the date, month and year elements of inner dob struct variable are accessed as "ptr → d1.d", "ptr → d1.m" and "ptr → d1.y" expressions.

#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;
}

当你运行这段代码时,它将产生以下输出:

When you run this code, it will produce the following output −

Name: Kiran
Salary: 25000.000000
Date of Birth: 12-5-1990