C語言中的結(jié)構(gòu)體的入門學(xué)習(xí)教程
C語言中數(shù)組允許定義類型的變量,可容納相同類型的多個數(shù)據(jù)項(xiàng),但結(jié)構(gòu)體在C語言編程中,它允許定義不同種類的數(shù)據(jù)項(xiàng)可供其他用戶定義的數(shù)據(jù)類型。
結(jié)構(gòu)是用來代表一個記錄,假設(shè)要跟蹤圖書館的書籍??赡芤櫽嘘P(guān)每本書以下屬性:
- Title - 標(biāo)題
- Author - 作者
- Subject - 科目
- Book ID - 編號
定義結(jié)構(gòu)體
定義一個結(jié)構(gòu)體,必須使用結(jié)構(gòu)體的struct語句。該struct語句定義了一個新的數(shù)據(jù)類型,程序不止一個成員。struct語句的格式是這樣的:
struct [structure tag] { member definition; member definition; ... member definition; } [one or more structure variables];
結(jié)構(gòu)體(structure)標(biāo)簽是可選的,每個成員的定義是一個正常的變量定義,如 int i; 或 float f; 或任何其他有效的變量的定義。在結(jié)構(gòu)的定義的結(jié)尾,最后的分號之前,可以指定一個或多個結(jié)構(gòu)變量,但它是可選的。這里是聲明書(Book)的結(jié)構(gòu)方式:
struct Books { char title[50]; char author[50]; char subject[100]; int book_id; } book;
訪問結(jié)構(gòu)體成員
要訪問結(jié)構(gòu)體的任何成員,我們使用成員訪問運(yùn)算符(.)成員訪問運(yùn)算符是編碼作為結(jié)構(gòu)體變量名,并且希望訪問結(jié)構(gòu)體部件。使用struct關(guān)鍵字來定義結(jié)構(gòu)體類型的變量。以下為例子來解釋結(jié)構(gòu)的用法:
#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; /* 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 : %s ", Book1.title); printf( "Book 1 author : %s ", Book1.author); printf( "Book 1 subject : %s ", Book1.subject); printf( "Book 1 book_id : %d ", Book1.book_id); /* print Book2 info */ printf( "Book 2 title : %s ", Book2.title); printf( "Book 2 author : %s ", Book2.author); printf( "Book 2 subject : %s ", Book2.subject); printf( "Book 2 book_id : %d ", Book2.book_id); return 0; }
讓我們編譯和運(yùn)行上面的程序,這將產(chǎn)生以下結(jié)果:
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ù)
可以傳遞一個結(jié)構(gòu)作為函數(shù)的參數(shù),非常類似傳遞任何其他變量或指針。訪問可以象在上面的例子已經(jīng)訪問類似結(jié)構(gòu)變量的方式:
#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 ", book.title); printf( "Book author : %s ", book.author); printf( "Book subject : %s ", book.subject); printf( "Book book_id : %d ", book.book_id); }
讓我們編譯和運(yùn)行上面的程序,這將產(chǎn)生以下結(jié)果:
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
指針結(jié)構(gòu)
非常相似定義指針結(jié)構(gòu),來定義指向任何其他變量,如下所示:
struct Books *struct_yiibaier;
現(xiàn)在,可以存儲結(jié)構(gòu)變量的地址在上面定義的指針變量。為了找到一個結(jié)構(gòu)變量的地址,將使用運(yùn)算符&在結(jié)構(gòu)體的名字之前,如下所示:
struct_yiibaier = &Book1;
訪問使用一個指向結(jié)構(gòu)的結(jié)構(gòu)的成員,必須使用 -> 運(yùn)算符如下:
struct_yiibaier->title;
讓我們重新寫上面的例子中使用結(jié)構(gòu)指針,希望這將能夠讓我們更容易地理解概念:
#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 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 : %s ", book->title); printf( "Book author : %s ", book->author); printf( "Book subject : %s ", book->subject); printf( "Book book_id : %d ", book->book_id); }
讓我們編譯和運(yùn)行上面的程序,這將產(chǎn)生以下結(jié)果:
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
位字段
位字段允許數(shù)據(jù)在一個結(jié)構(gòu)體包裝。這是特別有用的,當(dāng)內(nèi)存或存儲數(shù)據(jù)非常寶貴。典型的例子:
包裝幾個對象到一個機(jī)器語言。例如1位標(biāo)志能夠壓縮長度
讀取外部的文件格式 - 非標(biāo)準(zhǔn)的文件格式可以讀出。例如: 9位整數(shù)。
C語言允許我們通過結(jié)構(gòu)定義: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位標(biāo)志s f1..f3, 一個 4 位類型和9位my_int。
C語言自動包裝上述位字段盡可能緊湊,條件是字段的最大長度小于或等于計(jì)算機(jī)的整數(shù)字長。如果不是這種情況,那么一些編譯器可以允許,而其他將重疊存儲在下一個字段的存儲器。
指針和數(shù)組:
這是永遠(yuǎn)繞不開的話題,首先是引用:
struct stuff *ref = &Huqinwei; ref->age = 100; printf("age is:%d\n",Huqinwei.age);
打印可見變化
指針也是一樣的
struct stuff *ptr; ptr->age = 200; printf("age is:%d\n",Huqinwei.age);
結(jié)構(gòu)體也不能免俗,必須有數(shù)組:
struct test{ int a[3]; int b; }; //對于數(shù)組和變量同時存在的情況,有如下定義方法: struct test student[3] = {{{66,77,55},0}, {{44,65,33},0}, {{46,99,77},0}}; //特別的,可以簡化成: struct test student[3] = {{66,77,55,0}, {44,65,33,0}, {46,99,77,0}};
變長結(jié)構(gòu)體:
可以變長的數(shù)組
#include <stdio.h> #include <malloc.h> #include <string.h> typedef struct changeable{ int iCnt; char pc[0]; }schangeable; main(){ printf("size of struct changeable : %d\n",sizeof(schangeable)); schangeable *pchangeable = (schangeable *)malloc(sizeof(schangeable) + 10*sizeof(char)); printf("size of pchangeable : %d\n",sizeof(pchangeable)); schangeable *pchangeable2 = (schangeable *)malloc(sizeof(schangeable) + 20*sizeof(char)); pchangeable2->iCnt = 20; printf("pchangeable2->iCnt : %d\n",pchangeable2->iCnt); strncpy(pchangeable2->pc,"hello world",11); printf("%s\n",pchangeable2->pc); printf("size of pchangeable2 : %d\n",sizeof(pchangeable2)); }
運(yùn)行結(jié)果
size of struct changeable : 4 size of pchangeable : 4 pchangeable2->iCnt : 20 hello world size of pchangeable2 : 4
結(jié)構(gòu)體本身長度就是一個int長度(這個int值通常只為了表示后邊的數(shù)組長度),后邊的數(shù)組長度不計(jì)算在內(nèi),但是該數(shù)組可以直接使用。
(說后邊是個指針吧?指針也占長度!這個是不占的!原理很簡單,這個東西完全是數(shù)組后邊的尾巴,malloc開辟的是一片連續(xù)空間。其實(shí)這不應(yīng)該算一個機(jī)制,感覺應(yīng)該更像一個技巧吧)
結(jié)構(gòu)體嵌套:
結(jié)構(gòu)體嵌套其實(shí)沒有太意外的東西,只要遵循一定規(guī)律即可:
//對于“一錘子買賣”,只對最終的結(jié)構(gòu)體變量感興趣,其中A、B也可刪,不過最好帶著 struct A{ struct B{ int c; } b; } a; //使用如下方式訪問: a.b.c = 10;
特別的,可以一邊定義結(jié)構(gòu)體B,一邊就使用上:
struct A{ struct B{ int c; }b; struct B sb; }a;
使用方法與測試:
a.b.c = 11; printf("%d\n",a.b.c); a.sb.c = 22; printf("%d\n",a.sb.c);
結(jié)果無誤。
相關(guān)文章
C++語言基礎(chǔ) this和static關(guān)鍵字
這篇文章主要介紹了C++語言基礎(chǔ) this和static關(guān)鍵字,需要的朋友可以參考下2020-01-01c++實(shí)現(xiàn)逐行讀取配置文件寫入內(nèi)存的示例
這篇文章主要介紹了c++實(shí)現(xiàn)逐行讀取配置文件寫入內(nèi)存的示例,需要的朋友可以參考下2014-05-05詳解C語言中symlink()函數(shù)和readlink()函數(shù)的使用
這篇文章主要介紹了詳解C語言中symlink()函數(shù)和readlink()函數(shù)的使用,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-09-09Linux中rm命令使用以及C/C++代碼實(shí)現(xiàn)
m 是remove 的縮寫,Linux中 rm 命令的功能為刪除一個目錄中的一個或多個文件或目錄,它也可以將某個目錄及其下的所有文件及子目錄均刪除,這篇文章主要給大家介紹了關(guān)于Linux中rm命令使用以及C/C++代碼實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2022-04-04C++ main函數(shù)的幾點(diǎn)細(xì)節(jié)
這篇文章主要介紹了C++ main函數(shù)的幾點(diǎn)細(xì)節(jié),幫助大家更好的理解和學(xué)習(xí)C++,感興趣的朋友可以了解下2020-08-08