C语言结构体复习
參考:菜鳥教程
C語言結構體用得很多,這里重新撿拾并整理一下。
文章目錄
- 定義結構體
- 結構體變量初始化
- 訪問結構體成員
- 結構體作為函數參數
- 指向結構體的指針
- 位域
C 數組允許定義可存儲相同類型數據項的變量,而結構體允許用戶存儲不同類型的數據項。
定義結構體
為了定義結構體,需要使用struct語句,struct語句定義了一個包含多個成員的新的數據類型,struct語句的格式如下:
struct tag{member-listmember-listmember-list... }variable-list;這里的名稱解釋如下:
tag是結構體標簽。member-list是標準的變量定義,比如int i;variable-list是結構體變量,定義在結構體的末尾,最后一個分號之前,可以指定一個或者多個結構體變量。 在一般情況下,tag,member-list,variable-list這三部分至少要出現兩個。
下面是結構體的實例:
沒有標簽tag的情況:
//此聲明聲明了擁有三個成員的結構體,成員分別是int,char和double類型; //同時聲明了結構體變量s1; //該結構體沒有標簽tag struct {int a;char b;double c; }s1;沒有直接聲明結構體變量的情況:
//此聲明聲明了擁有三個成員的結構體,成員分別是int,char和double類型; //該結構體的標簽被命名為Sample,沒有聲明結構體變量。 struct Sample{int a;char b;double c; };//另外聲明結構體變量:t1,t2,t3struct Sample t1,t2[20],*t3;使用typedef創建新類型名
typedef struct{int a;char b;double c; }Sample2;//現在可以使用Sample2作為類型聲明新的結構體變量Sample2 u1,u2[30],*u3;在上面的聲明中,第一個和第二聲明被編譯器當作兩個完全不同的類型,即使他們的成員列表是一樣的,如果令 t3=&s1,則是非法的。
結構體的成員可以包含其他結構體,也可以包含指向自己結構體類型的指針,而通常這種指針的應用是為了實現一些更高級的數據結構如鏈表和樹等。
包含其他結構體的聲明
//此結構體的聲明包含了其他的結構體 struct Sample3{char string[100];struct Sample1 a; };包含指向自己類型的指針
//此結構體聲明包含了執行自己類型的指針 struct Node{char string[100];struct Node * next_node; };如果兩個結構體相互包含,則需要對其中一個結構體進行不完整聲明,如下所示:
struct B;//對結構體B進行不完整聲明//結構體中包含指向結構體B的指針 struct A{struct B *partner;//other elements; };//結構體B中包含指向結構體A的指針,在A聲明完后,B也隨之進行聲明 struct B{struct A *partner;//other elements; };結構體變量初始化
和其他類型變量一樣,對結構體變量可以在定義時指定初始值。
實例
運行結果
title:C language author:shizhengLi subject: programming language book_id:111111訪問結構體成員
為了訪問結構體的成員,我們使用成員訪問運算符(.)。成員訪問運算符是結構體變量名稱和我們要訪問的結構體成員之間的一個點號。可以使用關鍵字struct來定義結構體類型的變量。
實例
#include<stdio.h> #include<cstring>struct Books{char title[100];char author[50];char subject[100];int book_id; }; int main(){//printf("title:%s\nauthor:%s\nsubject: %s\nbook_id:%d\n",book.title,book.author,book.subject,book.book_id);struct Books Book1; //聲明變量Book1,類型是Books struct Books Book2; //聲明變量Book2,類型是Books//Book1詳述strcpy(Book1.title,"C language");strcpy(Book1.author,"shizhengLi");strcpy(Book1.subject,"programming language");Book1.book_id=000001;//Book2詳述strcpy(Book2.title,"C plus plus");strcpy(Book2.author,"shizhengLi");strcpy(Book2.subject,"programming language");Book2.book_id=000002;/* 輸出 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 language Book 1 author : shizhengLi Book 1 subject : programming language Book 1 book_id : 1 Book 2 title : C plus plus Book 2 author : shizhengLi Book 2 subject : programming language Book 2 book_id : 2結構體作為函數參數
也可以把結構體作為函數參數,傳參方式與其他類型的變量或指針類似。
實例
實現函數printBook(),用來打印Books結構體信息。
運行結果
我們發現和上例中輸出結果一致,但是少寫了很多重復代碼。
指向結構體的指針
可以定義指向結構體的指針,方式與定義指向其他類型的指針類似。
struct Books *struct_pointer;現在,可以在上述定義的指針變量中存儲結構變量的地址。為了查找結構變量的地址,請把 & 運算符放在結構體名稱的前面,如下所示:
struct_pointer=&Book2;為了使用指向該結構的指針訪問結構體的成員,必須使用->運算符,如下所示:
struct_pointer=->title;通過使用結構體指針重寫上面的例子
#include<stdio.h> #include<cstring>struct Books{char title[100];char author[50];char subject[100];int book_id; }; //函數聲明 void printBook(struct Books *book);int main(){//printf("title:%s\nauthor:%s\nsubject: %s\nbook_id:%d\n",book.title,book.author,book.subject,book.book_id);struct Books Book1; //聲明變量Book1,類型是Books struct Books Book2; //聲明變量Book2,類型是Books//Book1詳述strcpy(Book1.title,"C language");strcpy(Book1.author,"shizhengLi");strcpy(Book1.subject,"programming language");Book1.book_id=000001;//Book2詳述strcpy(Book2.title,"C plus plus");strcpy(Book2.author,"shizhengLi");strcpy(Book2.subject,"programming language");Book2.book_id=000002;/* 輸出 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); }位域
有些信息在存儲時,并不需要占用一個完整的字節,而只需占幾個或一個二進制位。例如在存放一個開關量時,只有 0 和 1 兩種狀態,用 1 位二進位即可。為了節省存儲空間,并使處理簡便,C 語言又提供了一種數據結構,稱為"位域"或"位段"。
所謂"位域"是把一個字節中的二進位劃分為幾個不同的區域,并說明每個區域的位數。每個域有一個域名,允許在程序中按域名進行操作。這樣就可以把幾個不同的對象用一個字節的二進制位域來表示。
典型的實例:
- 用 1 位二進位存放一個開關量時,只有 0 和 1 兩種狀態。
- 讀取外部文件格式——可以讀取非標準的文件格式。例如:9 位的整數。
位域的定義和位域變量的聲明
位域定義和結構體定義類似
struct 位域結構名{位域列表... };其中位域列表的形式為:
類型說明符 位域名:位域長度這里位域的知識暫時沒有整理。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
- 上一篇: GRE写作-政府官员必须执行人民意愿还是
- 下一篇: 《大话数据结构》读书笔记-线性表