struct結(jié)構(gòu)體數(shù)據(jù)類型
前言
我們知道,在C語言中有一些基本的數(shù)據(jù)類型,如charintfloatlongdoublestring(c99)
等等數(shù)據(jù)類型,他們可以表示一些事物的基本屬性,但是當(dāng)我們想表達一個事物的全部或部分屬性時,這時候再用單一的基本數(shù)據(jù)類型明顯就無法滿足需求了,這時候C提供了一種自定義數(shù)據(jù)類型,他可以封裝多個基本數(shù)據(jù)類型,這種數(shù)據(jù)類型叫結(jié)構(gòu)體,英文名稱struct,可以使用struct關(guān)鍵詞聲明結(jié)構(gòu)體
結(jié)構(gòu)體的聲明
結(jié)構(gòu)體的聲明語法如下
struct [structure tag] /*結(jié)構(gòu)體的標(biāo)簽*/{ member definition; /*零個或多個成員變量的定義*/ member definition; ... member definition; } [one or more structure variables]; /*一個或多個結(jié)構(gòu)體變量的定義*/
結(jié)構(gòu)體標(biāo)簽(structure tag)是可選的,但是推薦還是寫上,這樣使得代碼更加規(guī)范清晰,成員變量的定義一般為基本數(shù)據(jù)類型,如int age;char name[10]等,成員變量之間使用;隔開,最后一個成員變量后面的;可選, 如下面定義一個圖書信息的結(jié)構(gòu)體變量
struct Books {
char title[50];
char author[50];
char subject[100];
int book_id;
} book;
如下所示
struct Books {
char title[50];
char author[50];
char subject[100];
int book_id
} book;
我省略了最后一個成員變量后面的分號;代碼可以正常運行,但是當(dāng)我使用gcc編譯的時候,出現(xiàn)了下面信息
gcc struct.c ``` output ``` shell struct.c1: warning: no semicolon at end of struct or union } book; ^
這是警告提示,提示我們需要在struct和union數(shù)據(jù)類型定義的后面加上分號;,這樣的好處就是當(dāng)我們需要再添加一個成員變量的時候,只需寫上該成員變量的定義,而無需先敲;,我太機智了,手動滑稽...
沒有成員變量的結(jié)構(gòu)體
我們也可以定義一個空的結(jié)構(gòu)體,有時候我們需要某一個結(jié)構(gòu)體數(shù)據(jù)類型,但是暫時又不知道如何填充里面的成員變量,我們可以有如下定義
struct Books {
//TODO
} book;
訪問結(jié)構(gòu)體成員
定義完結(jié)構(gòu)體積后接下來就是去訪問它并給他賦值,為了訪問一個結(jié)構(gòu)體成員變量,我們可以使用成員操作符(.)成員訪問運算符被編碼為結(jié)構(gòu)變量名稱和我們希望訪問的結(jié)構(gòu)成員之間的句點(.)如下所示的完整代碼
struct.c
#include
#include
struct Books {
char title[50];
char author[50];
char subject[100];
int book_id;
};
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 */
printf( "Book 1 title : %sn", Book1.title);
printf( "Book 1 author : %sn", Book1.author);
printf( "Book 1 subject : %sn", Book1.subject);
printf( "Book 1 book_id : %dn", Book1.book_id);
/* print Book2 info */
printf( "Book 2 title : %sn", Book2.title);
printf( "Book 2 author : %sn", Book2.author);
printf( "Book 2 subject : %sn", Book2.subject);
printf( "Book 2 book_id : %dn", Book2.book_id);
return 0;
}
編譯并執(zhí)行
gcc struct.c && ./a.out
輸出
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
結(jié)構(gòu)作為函數(shù)參數(shù)
同樣的,我們也可以像基本數(shù)據(jù)類型一樣,把結(jié)構(gòu)體作為函數(shù)的參數(shù),如下所示我們定義一個打印結(jié)構(gòu)體的函數(shù)
#include
#include
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 : %sn", book.title);
printf( "Book author : %sn", book.author);
printf( "Book subject : %sn", book.subject);
printf( "Book book_id : %dn", book.book_id);
}
編譯運行
gcc struct.c && ./a.out
輸出
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
結(jié)構(gòu)體的指針
我們也可以定義結(jié)構(gòu)體指針,像這樣
struct Books *struct_pointer;
現(xiàn)在你可以存放結(jié)構(gòu)體變量的地址在結(jié)構(gòu)體變量指針中.和基本數(shù)據(jù)類型的變量一樣,我們使用&操作符取一個變量的地址
struct_pointer = &Book1;
接下來就是使用結(jié)構(gòu)體指針去訪問成員變量了,訪問的操作符我們由原來的.變?yōu)?>,沒錯,這個是不是很形象呢?完整代碼如下
#include
#include
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 by passing address of Book1 */
printBook( &Book1 );
/* print Book2 info by passing address of Book2 */
printBook( &Book2 );
return 0;
}
void printBook( struct Books *book ) {
printf( "Book title : %sn", book->title);
printf( "Book author : %sn", book->author);
printf( "Book subject : %sn", book->subject);
printf( "Book book_id : %dn", book->book_id);
}
編譯運行
gcc struct.c && ./a.out
輸出
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
結(jié)構(gòu)體數(shù)組
#include
#include
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 books[2];
/* book 1 specification */
strcpy( books[0].title, "C Programming");
strcpy( books[0].author, "Nuha Ali");
strcpy( books[0].subject, "C Programming Tutorial");
books[0].book_id = 6495407;
/* book 2 specification */
strcpy( books[1].title, "Telecom Billing");
strcpy( books[1].author, "Zara Ali");
strcpy( books[1].subject, "Telecom Billing Tutorial");
books[1].book_id = 6495700;
/* print Book1 info by passing address of Book1 */
printBook( &books[0] );
/* print Book2 info by passing address of Book2 */
printBook( &books[1] );
return 0;
}
void printBook( struct Books *book ) {
printf( "Book title : %sn", book->title);
printf( "Book author : %sn", book->author);
printf( "Book subject : %sn", book->subject);
printf( "Book book_id : %dn", book->book_id);
}
編譯運行
gcc struct.c && ./a.out
輸出
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
結(jié)構(gòu)體的內(nèi)存計算
沒錯,估計你已經(jīng)知道了,結(jié)構(gòu)體變量的所占用內(nèi)存空間的大小為各成員變量所占空間之和,如下所示的結(jié)構(gòu)體占用內(nèi)存大小在注釋里面
#include
#include
struct Books {
};
int main( ) {
printf("%dn", (int) sizeof(struct Books)); /*0*/
return 0;
}
#include
#include
struct Books {
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main() {
printf("%dn", (int) sizeof(struct Books)); /*204*/
return 0;
}
位域
有時候我們內(nèi)存緊張的時候,我們可以使用位域定義結(jié)構(gòu)體成員變量,比如當(dāng)我們需要定義一個表示true或false的時候,如果想這樣定義
int isOpen;
明顯很浪費空間,因為一個真假值只需要一個字位表示,所以我們可以這樣定義
unsigned int isOpen:1;
但是如果你直接寫在函數(shù)中是會報錯的,我們應(yīng)該寫在結(jié)構(gòu)體中
int main() {
unsigned int isOpen:1; /*編譯無法通過*/
return 0;
}
正確姿勢
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;
C盡可能緊湊地自動打包上述位字段,前提是字段的最大長度小于或等于計算機的整數(shù)字長。如果不是這種情況,那么一些編譯器可能允許字段存儲器重疊,而其他編譯器會將下一個字段存儲在下一個字中。
#include
#include
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;
int main() {
printf("%dn", (int) sizeof(struct packed_struct));
return 0;
}
輸出結(jié)果 8
審核編輯 黃宇
-
C語言
+關(guān)注
關(guān)注
183文章
7634瀏覽量
144196 -
結(jié)構(gòu)體
+關(guān)注
關(guān)注
1文章
131瀏覽量
11272
發(fā)布評論請先 登錄
C語言結(jié)構(gòu)體對齊介紹
C語言中數(shù)組和結(jié)構(gòu)體的內(nèi)存表示和布局
詳細講解c語言enum枚舉類型
漫談C語言結(jié)構(gòu)體
【干貨】c語言基礎(chǔ)語法——結(jié)構(gòu)體
結(jié)構(gòu)體的相關(guān)資料下載
c語言_結(jié)構(gòu)體和共同體
C語言程序設(shè)計教程之選擇結(jié)構(gòu)的資料講解
C語言程序設(shè)計教程之結(jié)構(gòu)體與共用體的詳細資料說明
干貨|手把手教你寫單片機的C語言結(jié)構(gòu)體
C語言-結(jié)構(gòu)體與位域
C語言入門之結(jié)構(gòu)體指針
C語言結(jié)構(gòu)體完全筆記

C語言結(jié)構(gòu)體史上最詳細的講解【軟件干貨】
評論