Objective-C結構體

Objective-C數組可定義包含多個相同類型的資料項目的變數類型,但結構體是Objective-C編程中的另一個用戶定義數據類型,它可組合不同類型的資料項目。

結構體用於表示記錄,假設要圖書館中跟蹤書籍資訊。可能希望跟蹤每本書的以下屬性 -

  • 標題
  • 作者
  • 學科
  • 書名

1. 定義結構體

要定義結構體,必須使用struct語句。 struct語句定義一個新的數據類型,為程式提供多個成員。 struct語句的格式如下所示 -

struct [structure tag] {
   member definition;
   member definition;
   ...
   member definition;
} [one or more structure variables];

structure tag是可選的,每個成員定義是一個普通的變數定義,例如int i;float f;或任何其他有效的變數定義。 在結構體定義的最後,在最後一個分號之前,可以指定一個或多個結構變數,但它是可選的。以下是聲明Book結構體的示例 -

struct Books {
   NSString *title;
   NSString *author;
   NSString *subject;
   int   book_id;
} book;

2. 訪問結構成員

要訪問結構的任何成員,使用成員訪問運算符(.)。成員訪問運算符是結構體變數名稱和要訪問結構體成員之間使用句點(.)連接。使用struct關鍵字來定義結構類型的變數。以下是結構體用法的示例 -

#import <Foundation/Foundation.h>

struct Books {
   NSString *title;
   NSString *author;
   NSString *subject;
   int   book_id;
};

int main() {
   struct Books Book1;        /* 聲明Book類型變數:Book1 */
   struct Books Book2;        /* 聲明Book類型變數:Book2 */

   /* book 1 指定值 */
   Book1.title = @"Objective-C編程";
   Book1.author = @"zaixian";
   Book1.subject = @"Objective-C編程教學";
   Book1.book_id = 81234566;

   /* book 2 指定值 */
   Book2.title = @"Java編程";
   Book2.author = @"Maxsu";
   Book2.subject = @"JavaC編程教學";
   Book2.book_id = 813283488;

   /* 列印 Book1 資訊 */
   NSLog(@"Book 1 title : %@\n", Book1.title);
   NSLog(@"Book 1 author : %@\n", Book1.author);
   NSLog(@"Book 1 subject : %@\n", Book1.subject);
   NSLog(@"Book 1 book_id : %d\n", Book1.book_id);

   /* 列印 Book2 資訊 */
   NSLog(@"Book 2 title : %@\n", Book2.title);
   NSLog(@"Book 2 author : %@\n", Book2.author);
   NSLog(@"Book 2 subject : %@\n", Book2.subject);
   NSLog(@"Book 2 book_id : %d\n", Book2.book_id);

   return 0;
}

執行上面示例代碼,得到以下結果 -

2018-11-15 07:18:43.096 main[21248] Book 1 title : Objective-C編程
2018-11-15 07:18:43.098 main[21248] Book 1 author : zaixian
2018-11-15 07:18:43.098 main[21248] Book 1 subject : Objective-C編程教學
2018-11-15 07:18:43.098 main[21248] Book 1 book_id : 81234566
2018-11-15 07:18:43.098 main[21248] Book 2 title : Java編程
2018-11-15 07:18:43.098 main[21248] Book 2 author : Maxsu
2018-11-15 07:18:43.098 main[21248] Book 2 subject : JavaC編程教學
2018-11-15 07:18:43.098 main[21248] Book 2 book_id : 813283488

3. 結構體作為函數參數

可以將結構體作為函數參數傳遞,與傳遞任何其他變數或指針的方式非常相似。將以與上面示例中訪問的方式類似,訪問結構體變數如下代碼 -

#import <Foundation/Foundation.h>

struct Books {
   NSString *title;
   NSString *author;
   NSString *subject;
   int   book_id;
};

@interface SampleClass:NSObject
/* 函數聲明 */
- (void) printBook:( struct Books) book ;
@end

@implementation SampleClass

- (void) printBook:( struct Books) book {
   NSLog(@"Book title : %@\n", book.title);
   NSLog(@"Book author : %@\n", book.author);
   NSLog(@"Book subject : %@\n", book.subject);
   NSLog(@"Book book_id : %d\n", book.book_id);
}

@end

int main() {
   struct Books Book1;        /* 聲明 Book類型變數 Book1 */
   struct Books Book2;        /* 聲明 Book類型變數 Book2 */

   /* book 1 設置成員資訊 */
   Book1.title = @"Objective-C編程";
   Book1.author = @"zaixian";
   Book1.subject = @"Objective-C編程教學";
   Book1.book_id = 88774078;

   /* book 2 設置成員資訊 */
   Book2.title = @"數據結構與演算法";
   Book2.author = @"Max su";
   Book2.subject = @"數據結構與演算法教學";
   Book2.book_id = 8899700;

   SampleClass *sampleClass = [[SampleClass alloc]init];
   /* print Book1 info */
   [sampleClass printBook: Book1];

   /* Print Book2 info */
   [sampleClass printBook: Book2];

   return 0;
}

執行上面示例代碼,得到以下結果 -

2018-11-15 07:24:14.437 main[50299] Book title : Objective-C編程
2018-11-15 07:24:14.439 main[50299] Book author : zaixian
2018-11-15 07:24:14.439 main[50299] Book subject : Objective-C編程教學
2018-11-15 07:24:14.439 main[50299] Book book_id : 88774078
2018-11-15 07:24:14.439 main[50299] Book title : 數據結構與演算法
2018-11-15 07:24:14.439 main[50299] Book author : Max su
2018-11-15 07:24:14.439 main[50299] Book subject : 數據結構與演算法教學
2018-11-15 07:24:14.439 main[50299] Book book_id : 8899700

4. 指向結構的指針

按照與定義指向變數的指針相似的方式來定義指向結構體的指針,如下所示 -

struct Books *struct_pointer;

現在,可以將結構體變數的地址存儲在上面定義的指針變數中。 要查找結構變數的地址,請使用&運算符放在結構體名稱之前,如下所示 -

struct_pointer = &Book1;

要使用指向結構體的指針訪問結構體的成員,必須使用 -> 運算符,如下所示 -

struct_pointer->title;

使用結構體指針重新編寫上面的例子,希望讀者容易理解 -

#import <Foundation/Foundation.h>

struct Books {
   NSString *title;
   NSString *author;
   NSString *subject;
   int   book_id;
};

@interface SampleClass:NSObject
/* function declaration */
- (void) printBook:( struct Books *) book ;
@end

@implementation SampleClass
- (void) printBook:( struct Books *) book {
   NSLog(@"Book title : %@\n", book->title);
   NSLog(@"Book author : %@\n", book->author);
   NSLog(@"Book subject : %@\n", book->subject);
   NSLog(@"Book book_id : %d\n", book->book_id);
}

@end

int main() {
   struct Books Book1;        /* 聲明 Book 類型變數:Book1  */
   struct Books Book2;        /* 聲明 Book 類型變數:Book2  */

   /* book 1 設置成員的值 */
   Book1.title = @"Objective-C編程";
   Book1.author = @"Yii Bai";
   Book1.subject = @"Objective-C編程教學";
   Book1.book_id = 6495407;

   /* book 2 設置成員的值 */
   Book2.title = @"數據結構與演算法";
   Book2.author = @"Max Su";
   Book2.subject = @"數據結構與演算法教學";
   Book2.book_id = 6495700;

   SampleClass *sampleClass = [[SampleClass alloc]init];
   /* print Book1 info by passing address of Book1 */
   [sampleClass printBook:&Book1];

   /* print Book2 info by passing address of Book2 */
   [sampleClass printBook:&Book2];

   return 0;
}

執行上面示例代碼,得到以下結果 -

2018-11-15 07:33:26.044 main[114068] Book title : Objective-C編程
2018-11-15 07:33:26.046 main[114068] Book author : Yii Bai
2018-11-15 07:33:26.046 main[114068] Book subject : Objective-C編程教學
2018-11-15 07:33:26.046 main[114068] Book book_id : 6495407
2018-11-15 07:33:26.046 main[114068] Book title : 數據結構與演算法
2018-11-15 07:33:26.046 main[114068] Book author : Max Su
2018-11-15 07:33:26.046 main[114068] Book subject : 數據結構與演算法教學
2018-11-15 07:33:26.046 main[114068] Book book_id : 6495700

5. 位域

位字段允許在結構中打包數據。當記憶體或數據存儲非常寶貴時,這尤其有用。 下麵是一個典型例子 -

  • 將多個對象打包成機器字。 例如 可以壓縮1位標誌。
  • 讀取外部檔格式 - 可以讀入非標準檔格式。 9位整數。

Objective-C允許通過在變數之後放置:長度 來在結構定義中執行此操作。 例如 -

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位標誌f1..f3,4位類型和9my_int

Objective-C盡可能緊湊地自動打包上述位字段,前提是字段的最大長度小於或等於電腦的整數字長。 如果不是這種情況,那麼一些編譯器可能允許字段的記憶體重疊,而其他編譯器將下一個字段存儲在下一個字中。


上一篇: Objective-C字串 下一篇: Objective-C預處理器