C語言中結構體感悟

博文天下-lei發表於2018-03-10

今天看到一個有關C語言結構體的筆記,感覺很不錯,拿來回一下以前的結構體知識,

C語言中,陣列允許定義可儲存相同型別資料項的變數(例如int i,float a等),是屬於單一型別的,結構體是C語言中另一種使用者可以自定義(我的理解為按照使用者的想法可以隨意由基本型別組成的)的可用的資料型別,它允許使用者在儲存不同型別的資料項。

1、使用結構體來表示一條記錄,假設你想要跟蹤圖書館中書本的動態,你可以需要跟蹤每本書的多個屬性,例如下面的屬性,

Title         ----> 目錄

Author    ----> 作者

Subject   ----> 物件

BookID   ----> 書本ID

下面我們來定義一個結構體,首先你必須使用的是結構體的關鍵字struct,使用struct定義一個包含多個成員的新資料型別,struct語句的格式如下:

struct  [structure tag]

{

    member definition;

    member definition;

    .............

    member definition;

}[one or more structure variables];

其中的structure tag 是可以選擇的,每個member definition是標準的變數定義,比如int i;或者float f;

或者其他有效的變數定義。在結構定義的末尾,最後一個分號之前,你可以制定一個或者多個結構體變數,這個是可選的。下面是宣告Book結構體的方式:

struct Books

{

    char title[50];

    char author[50;

    char subject[100];

    int book_id;

}book;

2、訪問結構體成語

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

編輯環境是Win7+啊哈C編輯軟體

#include <stdio.h>
#include <stdlib.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 Programing");
    strcpy(Book1.author,"Nuha ali");
    strcpy(Book1.subject,"C Programing 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);
system("pause");
return 0;

}


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

#include <stdio.h>
#include <stdlib.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 Programing");
    strcpy(Book1.author,"Nuha ali");
    strcpy(Book1.subject,"C Programing 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);
    printbook(Book1);
    /******輸出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);
   printbook(Book2);
system("pause");
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);

}


3、指向結構體的指標

可以定義指向結構的指標,方式與定義指向其他型別變數的指標相似,如下所示,

現在,可以在上述定義的指標變數中儲存結構變數的地址。為了查詢結構變數的地址,請把&運算子放在結構名稱的前面,如下,

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

#include <stdio.h>
#include <stdlib.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 Programing");
    strcpy(Book1.author,"Nuha ali");
    strcpy(Book1.subject,"C Programing 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);
    printbook(&Book1);
    /******輸出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);
   printbook(&Book2);
system("pause");
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);
}


4、在結構體中,還有一個概念很重要,這也是上次面試一個考官出過的題目,就是考察位域的概念

有些資訊在儲存的時候,並不需要佔用一個完整的位元組,而只需佔用幾個或者一個二進位制位。例如在存放一個開關量時,只有0和1兩種狀態,用1位二進位制位即可,為了節省儲存空間,並使處理簡便,C語言又提供一種資料結構稱之為位域或者位段,

所謂的位段就是把一個位元組中的二進位制位劃分為不同的區域,並說明每個區域的位數,每個域有一個域名,允許程式中按域名進行操作,這樣就可以把幾個不同的物件用一個位元組的二進位制位域來表示。

典型的例項:

用1位二進位制儲存一個開關量時,只有0和1兩種狀態

讀取外部檔案格式--可以讀取非標準的檔案格式,例如;9位的整數

位域定義與結構定義相仿,其形式為:

struct 位域結構名

{

    位域列表;

};

其中位域列表的形式為:

例如:

struct bs

{

 int a:8;

int b:2;

int c:6;

}data;

說明data為bs變數,共佔兩個位元組。其中位域a佔8位,位域b佔2位,位域c佔6位

struct bs{

unsigned a :4;

unsigned :4;

unsigned b:4;

unsigned c:

}

這個位域定義中,a 佔第一個位元組的4位,後4位填0不使用,b從第二位元組開始,佔用4位,c佔用4位,

由於位區域不允許跨兩個位元組,因此位區域的長度不能大於一個位元組的長度,也就是說,不能超過8位二進位制,如果最大長度大於計算機整數字長,一些編譯器可能會允許區域的記憶體重疊,另外一些編譯器可能會把大衣一個區域的部分儲存在下一個字中,

位區域可以是無名位區域,這時候它只能用來作填充或者調整位置。無名的位區域是不能使用的。例如

struct k

{

    int a:1;

    int   :2;/*該2位不能使用*/

    int b:3;

    int c:2;

};

從以上的分析可以看出,位區域在本質上就是一種結構體型別,不過其成員是按二進位制位分配的,


相關文章