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 變數,book1book2。變數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 會自動儘可能緊湊地打包上述位域,前提是欄位的最大長度小於或等於計算機的整數字長。如果不是這種情況,則某些編譯器可能會允許欄位的記憶體重疊,而其他編譯器則會將下一個欄位儲存在下一個字中。

廣告