
- 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 - 返回語句
- 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 - 空指標
- 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 語言中的結構體是一種派生資料型別或使用者自定義資料型別。我們使用關鍵字struct來定義一個自定義的資料型別,該型別將不同型別的元素組合在一起。陣列和結構體之間的區別在於,陣列是相同型別元素的同構集合,而結構體可以包含不同型別的元素,這些元素儲存在一起並由名稱標識。
我們經常需要處理具有某種關係的不同資料型別的值。例如,一本書由其標題(字串)、作者(字串)、價格(雙精度浮點數)、頁數(整數)等描述。與其使用四個不同的變數,不如將這些值儲存在一個struct變數中。
宣告(建立)結構體
您可以使用"struct"關鍵字後跟結構體標籤(結構體名稱)來建立(宣告)結構體,並在花括號內宣告結構體的所有成員及其資料型別。
要定義結構體,必須使用struct語句。struct 語句定義了一種新的資料型別,該型別具有多個成員。
結構體宣告語法
宣告結構體的格式(語法)如下所示:
struct [structure tag]{ member definition; member definition; ... member definition; } [one or more structure variables];
結構體標籤是可選的,每個成員定義都是一個正常的變數定義,例如"int i;"或"float f;"或任何其他有效的變數定義。
在結構體定義的末尾,在最後一個分號之前,可以指定一個或多個結構體變數,但這是可選的。
示例
在下面的示例中,我們正在為 Book 宣告一個結構體,以儲存書籍的詳細資訊:
struct book{ char title[50]; char author[50]; double price; int pages; } book1;
這裡,我們在結構體定義的末尾聲明瞭結構體變數book1。但是,您也可以在不同的語句中單獨進行此操作。
結構體變數宣告
要訪問和操作結構體的成員,首先需要宣告其變數。要宣告結構體變數,請編寫結構體名稱以及"struct"關鍵字,後跟結構體變數的名稱。此結構體變數將用於訪問和操作結構體成員。
示例
以下語句演示瞭如何宣告(建立)結構體變數
struct book book1;
通常,結構體在程式中第一個函式定義之前、在include語句之後宣告。這樣,派生型別就可以用於在任何函式內部宣告其變數。
結構體初始化
初始化struct 變數是透過將每個元素的值放在花括號內來完成的。
示例
以下語句演示了結構體的初始化
struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325};
訪問結構體成員
要訪問結構體的成員,首先需要宣告一個結構體變數,然後使用點 (.) 運算子以及結構體變數。
示例 1
struct 變數 book1 的四個元素都是使用點 (.) 運算子訪問的。因此,"book1.title" 指的是標題元素,"book1.author" 是作者姓名,"book1.price" 是價格,"book1.pages" 是第四個元素(頁數)。
請看下面的例子:
#include <stdio.h> struct book{ char title[10]; char author[20]; double price; int pages; }; int main(){ struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325}; printf("Title: %s \n", book1.title); printf("Author: %s \n", book1.author); printf("Price: %lf\n", book1.price); printf("Pages: %d \n", book1.pages); printf("Size of book struct: %d", sizeof(struct book)); return 0; }
輸出
執行程式碼並檢查其輸出:
Title: Learn C Author: Dennis Ritchie Price: 675.500000 Pages: 325 Size of book struct: 48
示例 2
在上面的程式中,我們將進行一個小修改。在這裡,我們將型別定義和變數宣告放在一起,如下所示:
struct book{ char title[10]; char author[20]; double price; int pages; } book1;
請注意,如果以這種方式宣告 struct 變數,則不能使用花括號對其進行初始化。相反,需要分別為每個元素賦值。
#include <stdio.h> #include <string.h> struct book{ char title[10]; char author[20]; double price; int pages; } book1; int main(){ strcpy(book1.title, "Learn C"); strcpy(book1.author, "Dennis Ritchie"); book1.price = 675.50; book1.pages = 325; printf("Title: %s \n", book1.title); printf("Author: %s \n", book1.author); printf("Price: %lf \n", book1.price); printf("Pages: %d \n", book1.pages); return 0; }
輸出
執行此程式碼時,將產生以下輸出:
Title: Learn C Author: Dennis Ritchie Price: 675.500000 Pages: 325
複製結構體
可以使用賦值 (=) 運算子直接複製結構體。您還可以使用賦值運算子 (=) 將一個結構體的成員值賦給另一個結構體的成員。
讓我們有兩個 struct book 變數,book1 和book2。變數book1在宣告時進行了初始化,我們希望將其元素的相同值賦給book2。
我們可以分別為各個元素賦值,如下所示:
struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325}, book2; strcpy(book2.title, book1.title); strcpy(book2.author, book1.author); book2.price = book1.price; book2.pages = book1.pages;
請注意,使用strcpy() 函式為字串變數賦值,而不是使用"= 運算子"。
示例
您還可以將 book1 賦給 book2,以便 book1 的所有元素分別賦給 book2 的元素。請看下面的程式程式碼:
#include <stdio.h> #include <string.h> struct book{ char title[10]; char author[20]; double price; int pages; }; int main(){ struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325}, book2; book2 = book1; printf("Title: %s \n", book2.title); printf("Author: %s \n", book2.author); printf("Price: %lf \n", book1.price); printf("Pages: %d \n", book1.pages); printf("Size of book struct: %d", sizeof(struct book)); return 0; }
輸出
執行程式碼並檢查其輸出:
Title: Learn C Author: Dennis Ritchie Price: 675.500000 Pages: 325 Size of book struct: 48
結構體作為函式引數
您可以像傳遞任何其他變數或指標一樣,將結構體作為函式引數傳遞。
示例
請看下面的程式程式碼。它演示瞭如何將結構體作為函式引數傳遞:
#include <stdio.h> #include <string.h> struct Books{ char title[50]; char author[50]; char subject[100]; int book_id; }; /* function declaration */ void printBook(struct Books book); int main(){ struct Books Book1; /* Declare Book1 of type Book */ struct Books Book2; /* Declare Book2 of type Book */ /* book 1 specification */ strcpy(Book1.title, "C Programming"); strcpy(Book1.author, "Nuha Ali"); strcpy(Book1.subject, "C Programming Tutorial"); Book1.book_id = 6495407; /* book 2 specification */ strcpy(Book2.title, "Telecom Billing"); strcpy(Book2.author, "Zara Ali"); strcpy(Book2.subject, "Telecom Billing Tutorial"); Book2.book_id = 6495700; /* print Book1 info */ printBook(Book1); /* Print Book2 info */ printBook(Book2); return 0; } void printBook(struct Books book){ printf("Book title : %s\n", book.title); printf("Book author : %s\n", book.author); printf("Book subject : %s\n", book.subject); printf("Book book_id : %d\n", book.book_id); }
輸出
編譯並執行上述程式碼時,將產生以下結果:
Book title : C Programming Book author : Nuha Ali Book subject : C Programming Tutorial Book book_id : 6495407 Book title : Telecom Billing Book author : Zara Ali Book subject : Telecom Billing Tutorial Book book_id : 6495700
指向結構體的指標
您可以像定義指向任何其他變數的指標一樣定義指向結構體的指標。
指向結構體的指標宣告
您可以如下宣告指向結構體的指標(或結構體指標):
struct Books *struct_pointer;
指向結構體的指標初始化
您可以在上述指標變數struct_pointer中儲存結構體變數的地址。要查詢結構體變數的地址,請在結構體名稱前放置'&'運算子,如下所示:
struct_pointer = & book1;
讓我們將 struct 變數的地址儲存在 struct 指標變數中。
struct book{ char title[10]; char author[20]; double price; int pages; }; struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325}, struct book *strptr;
使用指向結構體的指標訪問成員
要使用指向該結構體的指標訪問結構體的成員,必須使用→ 運算子,如下所示:
struct_pointer->title;
C 定義→符號與 struct 指標一起用作間接運算子(也稱為結構體解引用運算子)。它有助於訪問 struct 變數的元素,該指標引用到該元素。
示例
在這個例子中,strptr 是指向 struct book book1 變數的指標。因此,strrptr→title 返回標題,就像 book1.title 一樣。
#include <stdio.h> #include <string.h> struct book{ char title[10]; char author[20]; double price; int pages; }; int main (){ struct book book1 = {"Learn C", "Dennis Ritchie", 675.50, 325}; struct book *strptr; strptr = &book1; printf("Title: %s \n", strptr -> title); printf("Author: %s \n", strptr -> author); printf("Price: %lf \n", strptr -> price); printf("Pages: %d \n", strptr -> pages); return 0; }
輸出
執行此程式碼時,將產生以下輸出:
Title: Learn C Author: Dennis Ritchie Price: 675.500000 Pages: 325
注意: 點 (.) 運算子用於透過 struct 變數訪問結構體元素。要透過其指標訪問元素,必須使用 間接訪問 (->) 運算子。
.結構體變數類似於基本型別的普通變數,因為它可以擁有結構體陣列,可以將結構體變數傳遞給函式,以及從函式返回結構體。
您可能已經注意到,在宣告變數或指標時需要在前面加上“struct 型別”。這可以透過使用 typedef 關鍵字建立簡寫符號來避免,我們將在後續章節中解釋。
結構體用於不同的應用程式,例如資料庫、檔案管理應用程式以及處理複雜的資料結構,如樹和連結串列。
位域
位域 允許在結構體中打包資料。當記憶體或資料儲存空間有限時,這尤其有用。典型示例包括:
- 將多個物件打包到一個機器字中,例如,可以壓縮 1 位標誌。
- 讀取外部檔案格式 - 例如,可以讀取非標準檔案格式,例如 9 位整數。
宣告
C 允許我們在結構體定義中透過在變數後面加上 :bit 長度來實現這一點。例如:
struct packed_struct{ unsigned int f1:1; unsigned int f2:1; unsigned int f3:1; unsigned int f4:1; unsigned int type:4; unsigned int my_int:9; } pack;
這裡,packed_struct 包含 6 個成員:四個 1 位標誌 f1..f3,一個 4 位型別和一個 9 位 my_int。
C 會自動儘可能緊湊地打包上述位域,前提是欄位的最大長度小於或等於計算機的整數字長。如果不是這種情況,則某些編譯器可能會允許欄位的記憶體重疊,而其他編譯器則會將下一個欄位儲存在下一個字中。