C 結構體

C 結構體

C 陣列允許定義可儲存相同型別資料項的變數,結構是 C 程式設計中另一種使用者自定義的可用的資料型別,它允許您儲存不同型別的資料項。

結構用於表示一條記錄,假設您想要跟蹤圖書館中書本的動態,您可能需要跟蹤每本書的下列屬性:

  • Title
  • Author
  • Subject
  • Book ID

定義結構

為了定義結構,您必須使用 struct 語句。struct 語句定義了一個包含多個成員的新的資料型別,struct 語句的格式如下:

struct tag { member-list member-list member-list ... } variable-list ;

tag 是結構體標籤。

member-list 是標準的變數定義,比如 int i; 或者 float f,或者其他有效的變數定義。

variable-list 結構變數,定義在結構的末尾,最後一個分號之前,您可以指定一個或多個結構變數。下面是宣告 Book 結構的方式:

struct Books { char title[50]; char author[50]; char subject[100]; int book_id; } book;

在一般情況下,tag、member-list、variable-list 這 3 部分至少要出現 2 個。以下為例項:

//此宣告聲明瞭擁有3個成員的結構體,分別為整型的a,字元型的b和雙精度的c //同時又聲明瞭結構體變數s1 //這個結構體並沒有標明其標籤 struct { int a; char b; double c; } s1; //此宣告聲明瞭擁有3個成員的結構體,分別為整型的a,字元型的b和雙精度的c //結構體的標籤被命名為SIMPLE,沒有宣告變數 struct SIMPLE { int a; char b; double c; }; //用SIMPLE標籤的結構體,另外聲明瞭變數t1、t2、t3 struct SIMPLE t1, t2[20], *t3; //也可以用typedef建立新型別 typedef struct { int a; char b; double c; } Simple2; //現在可以用Simple2作為型別宣告新的結構體變數 Simple2 u1, u2[20], *u3;

在上面的宣告中,第一個和第二宣告被編譯器當作兩個完全不同的型別,即使他們的成員列表是一樣的,如果令 t3=&s1,則是非法的。

結構體的成員可以包含其他結構體,也可以包含指向自己結構體型別的指標,而通常這種指標的應用是為了實現一些更高階的資料結構如連結串列和樹等。

//此結構體的宣告包含了其他的結構體 struct COMPLEX { char string[100]; struct SIMPLE a; }; //此結構體的宣告包含了指向自己型別的指標 struct NODE { char string[100]; struct NODE *next_node; };

如果兩個結構體互相包含,則需要對其中一個結構體進行不完整宣告,如下所示:

struct B; //對結構體B進行不完整宣告 //結構體A中包含指向結構體B的指標 struct A { struct B *partner; //other members; }; //結構體B中包含指向結構體A的指標,在A宣告完後,B也隨之進行宣告 struct B { struct A *partner; //other members; };

結構體變數的初始化

和其它型別變數一樣,對結構體變數可以在定義時指定初始值。

例項

#include <stdio.h> struct Books { char title[50]; char author[50]; char subject[100]; int book_id; } book = {"C 語言", "itread01", "程式語言", 123456}; int main() { printf("title : %s\nauthor: %s\nsubject: %s\nbook_id: %d\n", book.title, book.author, book.subject, book.book_id); }

執行輸出結果為:

title : C 語言
author: itread01
subject: 程式語言
book_id: 123456

訪問結構成員

為了訪問結構的成員,我們使用成員訪問運算子(.)。成員訪問運算子是結構變數名稱和我們要訪問的結構成員之間的一個句號。您可以使用 struct 關鍵字來定義結構型別的變數。下面的例項演示了結構的用法:

例項

#include <stdio.h> #include <string.h> struct Books { char title[50]; char author[50]; char subject[100]; int book_id; }; int main( ) { struct Books Book1; /* 宣告 Book1,型別為 Books */ struct Books Book2; /* 宣告 Book2,型別為 Books */ /* Book1 詳述 */ strcpy( Book1.title, "C Programming"); strcpy( Book1.author, "Nuha Ali"); strcpy( Book1.subject, "C Programming Tutorial"); Book1.book_id = 6495407; /* Book2 詳述 */ strcpy( Book2.title, "Telecom Billing"); strcpy( Book2.author, "Zara Ali"); strcpy( Book2.subject, "Telecom Billing Tutorial"); Book2.book_id = 6495700; /* 輸出 Book1 資訊 */ printf( "Book 1 title : %s\n", Book1.title); printf( "Book 1 author : %s\n", Book1.author); printf( "Book 1 subject : %s\n", Book1.subject); printf( "Book 1 book_id : %d\n", Book1.book_id); /* 輸出 Book2 資訊 */ printf( "Book 2 title : %s\n", Book2.title); printf( "Book 2 author : %s\n", Book2.author); printf( "Book 2 subject : %s\n", Book2.subject); printf( "Book 2 book_id : %d\n", Book2.book_id); return 0; }

當上面的程式碼被編譯和執行時,它會產生下列結果:

Book 1 title : C Programming
Book 1 author : Nuha Ali
Book 1 subject : C Programming Tutorial
Book 1 book_id : 6495407
Book 2 title : Telecom Billing
Book 2 author : Zara Ali
Book 2 subject : Telecom Billing Tutorial
Book 2 book_id : 6495700

結構作為函式引數

您可以把結構作為函式引數,傳參方式與其他型別的變數或指標類似。您可以使用上面例項中的方式來訪問結構變數:

例項

#include <stdio.h> #include <string.h> struct Books { char title[50]; char author[50]; char subject[100]; int book_id; }; /* 函式宣告 */ void printBook( struct Books book ); int main( ) { struct Books Book1; /* 宣告 Book1,型別為 Books */ struct Books Book2; /* 宣告 Book2,型別為 Books */ /* Book1 詳述 */ strcpy( Book1.title, "C Programming"); strcpy( Book1.author, "Nuha Ali"); strcpy( Book1.subject, "C Programming Tutorial"); Book1.book_id = 6495407; /* Book2 詳述 */ strcpy( Book2.title, "Telecom Billing"); strcpy( Book2.author, "Zara Ali"); strcpy( Book2.subject, "Telecom Billing Tutorial"); Book2.book_id = 6495700; /* 輸出 Book1 資訊 */ printBook( Book1 ); /* 輸出 Book2 資訊 */ 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 = &Book1;

為了使用指向該結構的指標訪問結構的成員,您必須使用 -> 運算子,如下所示:

struct_pointer->title;

讓我們使用結構指標來重寫上面的例項,這將有助於您理解結構指標的概念:

例項

#include <stdio.h> #include <string.h> struct Books { char title[50]; char author[50]; char subject[100]; int book_id; }; /* 函式宣告 */ void printBook( struct Books *book ); int main( ) { struct Books Book1; /* 宣告 Book1,型別為 Books */ struct Books Book2; /* 宣告 Book2,型別為 Books */ /* Book1 詳述 */ strcpy( Book1.title, "C Programming"); strcpy( Book1.author, "Nuha Ali"); strcpy( Book1.subject, "C Programming Tutorial"); Book1.book_id = 6495407; /* Book2 詳述 */ strcpy( Book2.title, "Telecom Billing"); strcpy( Book2.author, "Zara Ali"); strcpy( Book2.subject, "Telecom Billing Tutorial"); Book2.book_id = 6495700; /* 通過傳 Book1 的地址來輸出 Book1 資訊 */ printBook( &Book1 ); /* 通過傳 Book2 的地址來輸出 Book2 資訊 */ 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