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”元素:dmy。“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
廣告