0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

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

哈哈hfgfdf ? 來源:嵌入式學習資料 ? 作者:嵌入式學習資料 ? 2024-03-28 17:52 ? 次閱讀

struct結(jié)構(gòu)體數(shù)據(jù)類型

前言

我們知道,在C語言中有一些基本的數(shù)據(jù)類型,如charintfloatlongdoublestring(c99)

等等數(shù)據(jù)類型,他們可以表示一些事物的基本屬性,但是當我們想表達一個事物的全部或部分屬性時,這時候再用單一的基本數(shù)據(jù)類型明顯就無法滿足需求了,這時候C提供了一種自定義數(shù)據(jù)類型,他可以封裝多個基本數(shù)據(jù)類型,這種數(shù)據(jù)類型叫結(jié)構(gòu)體,英文名稱struct,可以使用struct關鍵詞聲明結(jié)構(gòu)體

結(jié)構(gòu)體的聲明

結(jié)構(gòu)體的聲明語法如下

struct [structure tag] /*結(jié)構(gòu)體的標簽*/{

   member definition; /*零個或多個成員變量的定義*/
   member definition;
   ...
   member definition;
} [one or more structure variables];  /*一個或多個結(jié)構(gòu)體變量的定義*/

結(jié)構(gòu)體標簽(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;

我省略了最后一個成員變量后面的分號;代碼可以正常運行,但是當我使用gcc編譯的時候,出現(xiàn)了下面信息

gcc struct.c
```
 output
``` shell
struct.c1: warning: no semicolon at end of struct or union
 } book;
 ^

這是警告提示,提示我們需要在struct和union數(shù)據(jù)類型定義的后面加上分號;,這樣的好處就是當我們需要再添加一個成員變量的時候,只需寫上該成員變量的定義,而無需先敲;,我太機智了,手動滑稽...

沒有成員變量的結(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)體成員變量,比如當我們需要定義一個表示true或false的時候,如果想這樣定義

int isOpen;

明顯很浪費空間,因為一個真假值只需要一個字位表示,所以我們可以這樣定義

unsigned int isOpen:1;

但是如果你直接寫在函數(shù)中是會報錯的,我們應該寫在結(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

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7594

    瀏覽量

    135863
  • 結(jié)構(gòu)體

    關注

    1

    文章

    129

    瀏覽量

    10823
收藏 人收藏

    評論

    相關推薦

    C語言結(jié)構(gòu)對齊介紹

    大家好,我是嵌入式老林,從事嵌入式軟件開發(fā)多年,今天分享的內(nèi)容是C語言結(jié)構(gòu)對齊介紹,希望能對你有所幫助
    發(fā)表于 07-11 11:50 ?2381次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>結(jié)構(gòu)</b><b class='flag-5'>體</b>對齊介紹

    C語言中數(shù)組和結(jié)構(gòu)的內(nèi)存表示和布局

    C語言中,數(shù)組和結(jié)構(gòu)都可以代表一塊內(nèi)存,但為什么結(jié)構(gòu)可以直接賦值,而數(shù)組不可以?這個問題涉及
    發(fā)表于 08-28 10:54 ?1394次閱讀

    詳細講解c語言enum枚舉類型

    詳細講解C語言enum枚舉類型在實際應用中,有的變量只有幾種可能取值。如人的性別只有兩種可能取值,星期只有七種可能取值。在 C
    發(fā)表于 12-21 23:22

    漫談C語言結(jié)構(gòu)

      相信大家對于結(jié)構(gòu)都不陌生。在此,分享出本人對c語言結(jié)構(gòu)的學習心得。如果你發(fā)現(xiàn)這個總結(jié)中有
    發(fā)表于 11-15 15:59

    干貨c語言基礎語法——結(jié)構(gòu)

    1、關于C語言結(jié)構(gòu)的引入在實際問題中有時候我們需要幾種數(shù)據(jù)類型一起來修飾某個變量。例如一個學生的信息就需要學號(字符串),姓名(字符串),年齡(整形)等等。這些數(shù)據(jù)類型都不同但是他們
    發(fā)表于 06-03 17:10

    結(jié)構(gòu)的相關資料下載

    擊上方“果果小師弟”,選擇“置頂/星標公眾號”干貨福利,第一時間送達!摘要:聽說還有好多學單片機的小伙伴不會用結(jié)構(gòu)?指針和結(jié)構(gòu)是學單片機
    發(fā)表于 01-07 08:25

    怎樣去使用C語言結(jié)構(gòu)和共用

    C語言結(jié)構(gòu)和共用分別有何特點呢?怎樣去使用C語言
    發(fā)表于 01-17 07:51

    c語言_結(jié)構(gòu)和共同體

    這份PPT很全面講解了結(jié)構(gòu)的各種用法,夠全面,對結(jié)構(gòu)的各種應用也舉了例子,本人已驗證過的!另外也講解了共同體和枚舉,這兩部分描述較少。
    發(fā)表于 06-15 10:58 ?0次下載

    C語言程序設計教程之選擇結(jié)構(gòu)的資料講解

    本文檔的主要內(nèi)容詳細介紹的是C語言程序設計教程之選擇結(jié)構(gòu)的資料講解主要內(nèi)容包括了:1 語句與復合語句,2 if 語 句,3 if…else
    發(fā)表于 01-08 14:19 ?11次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>程序設計教程之選擇<b class='flag-5'>結(jié)構(gòu)</b>的資料<b class='flag-5'>講解</b>

    C語言程序設計教程之結(jié)構(gòu)與共用詳細資料說明

    本文檔詳細介紹的是C語言程序設計教程之結(jié)構(gòu)與共用詳細
    發(fā)表于 03-01 17:20 ?11次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>程序設計教程之<b class='flag-5'>結(jié)構(gòu)</b><b class='flag-5'>體</b>與共用<b class='flag-5'>體</b>的<b class='flag-5'>詳細</b>資料說明

    干貨|手把手教你寫單片機的C語言結(jié)構(gòu)

    摘要:聽說還有好多學單片機的小伙伴不會用結(jié)構(gòu)?指針和結(jié)構(gòu)是學單片機必須要掌握的,如果你C語言
    發(fā)表于 11-23 17:51 ?42次下載
    <b class='flag-5'>干貨</b>|手把手教你寫單片機的<b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>結(jié)構(gòu)</b><b class='flag-5'>體</b>

    C語言-結(jié)構(gòu)與位域

    C語言里的結(jié)構(gòu)是可以包含不同數(shù)據(jù)類型和相同數(shù)據(jù)類型的一個有序集合,屬于構(gòu)造類型,可以自己任意組合,并且結(jié)構(gòu)
    的頭像 發(fā)表于 08-14 10:06 ?1632次閱讀

    C語言入門之結(jié)構(gòu)指針

    C語言中,指向結(jié)構(gòu)對象的指針變量既可以指向結(jié)構(gòu)變量,也可指向
    的頭像 發(fā)表于 03-24 14:59 ?981次閱讀

    C語言結(jié)構(gòu)完全筆記

    我們剛剛申請了一個名叫Info的結(jié)構(gòu)類型,那么理論上我們可以像聲明其他變量的操作一樣,去聲明我們的結(jié)構(gòu)體操作,但是C語言中規(guī)定,聲明
    的頭像 發(fā)表于 08-01 16:52 ?560次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>結(jié)構(gòu)</b><b class='flag-5'>體</b>完全筆記

    C語言C++中結(jié)構(gòu)的區(qū)別

    同樣是結(jié)構(gòu),看看在C語言C++中有什么區(qū)別?
    的頭像 發(fā)表于 10-30 15:11 ?103次閱讀