
- 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