Objective-C數組可定義包含多個相同類型的數據項的變量類型,但結構體是Objective-C編程中的另一個用戶定義數據類型,它可組合不同類型的數據項。
結構體用于表示記錄,假設要圖書館中跟蹤書籍信息。可能希望跟蹤每本書的以下屬性 -
- 標題
- 作者
- 學科
- 書名
1. 定義結構體
要定義結構體,必須使用struct
語句。 struct
語句定義一個新的數據類型,為程序提供多個成員。 struct
語句的格式如下所示 -
1 struct [structure tag] { 2 member definition; 3 member definition; 4 ... 5 member definition; 6 } [one or more structure variables];
structure tag
是可選的,每個成員定義是一個普通的變量定義,例如int i;
或float f;
或任何其他有效的變量定義。 在結構體定義的最后,在最后一個分號之前,可以指定一個或多個結構變量,但它是可選的。以下是聲明Book
結構體的示例 -
1 struct Books { 2 NSString *title; 3 NSString *author; 4 NSString *subject; 5 int book_id; 6 } book;
2. 訪問結構成員
要訪問結構的任何成員,使用成員訪問運算符(.
)。成員訪問運算符是結構體變量名稱和要訪問結構體成員之間使用句點(.
)連接。使用struct
關鍵字來定義結構類型的變量。以下是結構體用法的示例 -
1 #import <Foundation/Foundation.h> 2 3 struct Books { 4 NSString *title; 5 NSString *author; 6 NSString *subject; 7 int book_id; 8 }; 9 10 int main() { 11 struct Books Book1; /* 聲明Book類型變量:Book1 */ 12 struct Books Book2; /* 聲明Book類型變量:Book2 */ 13 14 /* book 1 指定值 */ 15 Book1.title = @"Objective-C編程"; 16 Book1.author = @"Yiibai"; 17 Book1.subject = @"Objective-C編程教程"; 18 Book1.book_id = 81234566; 19 20 /* book 2 指定值 */ 21 Book2.title = @"Java編程"; 22 Book2.author = @"Maxsu"; 23 Book2.subject = @"JavaC編程教程"; 24 Book2.book_id = 813283488; 25 26 /* 打印 Book1 信息 */ 27 NSLog(@"Book 1 title : %@\n", Book1.title); 28 NSLog(@"Book 1 author : %@\n", Book1.author); 29 NSLog(@"Book 1 subject : %@\n", Book1.subject); 30 NSLog(@"Book 1 book_id : %d\n", Book1.book_id); 31 32 /* 打印 Book2 信息 */ 33 NSLog(@"Book 2 title : %@\n", Book2.title); 34 NSLog(@"Book 2 author : %@\n", Book2.author); 35 NSLog(@"Book 2 subject : %@\n", Book2.subject); 36 NSLog(@"Book 2 book_id : %d\n", Book2.book_id); 37 38 return 0; 39 }
執行上面示例代碼,得到以下結果 -
1 2018-11-15 07:18:43.096 main[21248] Book 1 title : Objective-C編程 2 2018-11-15 07:18:43.098 main[21248] Book 1 author : Yiibai 3 2018-11-15 07:18:43.098 main[21248] Book 1 subject : Objective-C編程教程 4 2018-11-15 07:18:43.098 main[21248] Book 1 book_id : 81234566 5 2018-11-15 07:18:43.098 main[21248] Book 2 title : Java編程 6 2018-11-15 07:18:43.098 main[21248] Book 2 author : Maxsu 7 2018-11-15 07:18:43.098 main[21248] Book 2 subject : JavaC編程教程 8 2018-11-15 07:18:43.098 main[21248] Book 2 book_id : 813283488
3. 結構體作為函數參數
可以將結構體作為函數參數傳遞,與傳遞任何其他變量或指針的方式非常相似。將以與上面示例中訪問的方式類似,訪問結構體變量如下代碼 -
1 #import <Foundation/Foundation.h> 2 3 struct Books { 4 NSString *title; 5 NSString *author; 6 NSString *subject; 7 int book_id; 8 }; 9 10 @interface SampleClass:NSObject 11 /* 函數聲明 */ 12 - (void) printBook:( struct Books) book ; 13 @end 14 15 @implementation SampleClass 16 17 - (void) printBook:( struct Books) book { 18 NSLog(@"Book title : %@\n", book.title); 19 NSLog(@"Book author : %@\n", book.author); 20 NSLog(@"Book subject : %@\n", book.subject); 21 NSLog(@"Book book_id : %d\n", book.book_id); 22 } 23 24 @end 25 26 int main() { 27 struct Books Book1; /* 聲明 Book類型變量 Book1 */ 28 struct Books Book2; /* 聲明 Book類型變量 Book2 */ 29 30 /* book 1 設置成員信息 */ 31 Book1.title = @"Objective-C編程"; 32 Book1.author = @"Yiibai"; 33 Book1.subject = @"Objective-C編程教程"; 34 Book1.book_id = 88774078; 35 36 /* book 2 設置成員信息 */ 37 Book2.title = @"數據結構與算法"; 38 Book2.author = @"Strengthen"; 39 Book2.subject = @"數據結構與算法教程"; 40 Book2.book_id = 8899700; 41 42 SampleClass *sampleClass = [[SampleClass alloc]init]; 43 /* print Book1 info */ 44 [sampleClass printBook: Book1]; 45 46 /* Print Book2 info */ 47 [sampleClass printBook: Book2]; 48 49 return 0; 50 }
執行上面示例代碼,得到以下結果 -
1 2018-11-15 07:24:14.437 main[50299] Book title : Objective-C編程 2 2018-11-15 07:24:14.439 main[50299] Book author : Yiibai 3 2018-11-15 07:24:14.439 main[50299] Book subject : Objective-C編程教程 4 2018-11-15 07:24:14.439 main[50299] Book book_id : 88774078 5 2018-11-15 07:24:14.439 main[50299] Book title : 數據結構與算法 6 2018-11-15 07:24:14.439 main[50299] Book author : Strengthen 7 2018-11-15 07:24:14.439 main[50299] Book subject : 數據結構與算法教程 8 2018-11-15 07:24:14.439 main[50299] Book book_id : 8899700
4. 指向結構的指針
按照與定義指向變量的指針相似的方式來定義指向結構體的指針,如下所示 -
struct Books *struct_pointer;
現在,可以將結構體變量的地址存儲在上面定義的指針變量中。 要查找結構變量的地址,請使用&
運算符放在結構體名稱之前,如下所示 -
struct_pointer = &Book1;
要使用指向結構體的指針訪問結構體的成員,必須使用 ->
運算符,如下所示 -
struct_pointer->title;
使用結構體指針重新編寫上面的例子,希望讀者容易理解 -
1 #import <Foundation/Foundation.h> 2 3 struct Books { 4 NSString *title; 5 NSString *author; 6 NSString *subject; 7 int book_id; 8 }; 9 10 @interface SampleClass:NSObject 11 /* function declaration */ 12 - (void) printBook:( struct Books *) book ; 13 @end 14 15 @implementation SampleClass 16 - (void) printBook:( struct Books *) book { 17 NSLog(@"Book title : %@\n", book->title); 18 NSLog(@"Book author : %@\n", book->author); 19 NSLog(@"Book subject : %@\n", book->subject); 20 NSLog(@"Book book_id : %d\n", book->book_id); 21 } 22 23 @end 24 25 int main() { 26 struct Books Book1; /* 聲明 Book 類型變量:Book1 */ 27 struct Books Book2; /* 聲明 Book 類型變量:Book2 */ 28 29 /* book 1 設置成員的值 */ 30 Book1.title = @"Objective-C編程"; 31 Book1.author = @"Yii Bai"; 32 Book1.subject = @"Objective-C編程教程"; 33 Book1.book_id = 6495407; 34 35 /* book 2 設置成員的值 */ 36 Book2.title = @"數據結構與算法"; 37 Book2.author = @"Strengthen"; 38 Book2.subject = @"數據結構與算法教程"; 39 Book2.book_id = 6495700; 40 41 SampleClass *sampleClass = [[SampleClass alloc]init]; 42 /* print Book1 info by passing address of Book1 */ 43 [sampleClass printBook:&Book1]; 44 45 /* print Book2 info by passing address of Book2 */ 46 [sampleClass printBook:&Book2]; 47 48 return 0; 49 }
執行上面示例代碼,得到以下結果 -
1 2018-11-15 07:33:26.044 main[114068] Book title : Objective-C編程 2 2018-11-15 07:33:26.046 main[114068] Book author : Yii Bai 3 2018-11-15 07:33:26.046 main[114068] Book subject : Objective-C編程教程 4 2018-11-15 07:33:26.046 main[114068] Book book_id : 6495407 5 2018-11-15 07:33:26.046 main[114068] Book title : 數據結構與算法 6 2018-11-15 07:33:26.046 main[114068] Book author : Strengthen 7 2018-11-15 07:33:26.046 main[114068] Book subject : 數據結構與算法教程 8 2018-11-15 07:33:26.046 main[114068] Book book_id : 6495700
5. 位域
位字段允許在結構中打包數據。當內存或數據存儲非常寶貴時,這尤其有用。 下面是一個典型例子 -
- 將多個對象打包成機器字。 例如 可以壓縮
1
位標志。 - 讀取外部文件格式 - 可以讀入非標準文件格式。
9
位整數。
Objective-C允許通過在變量之后放置:長度
來在結構定義中執行此操作。 例如 -
1 struct packed_struct { 2 unsigned int f1:1; 3 unsigned int f2:1; 4 unsigned int f3:1; 5 unsigned int f4:1; 6 unsigned int type:4; 7 unsigned int my_int:9; 8 } pack;
這里,packed_struct
包含6
個成員:四個1
位標志f1..f3
,4
位類型和9
位my_int
。
Objective-C盡可能緊湊地自動打包上述位字段,前提是字段的最大長度小于或等于計算機的整數字長。 如果不是這種情況,那么一些編譯器可能允許字段的存儲器重疊,而其他編譯器將下一個字段存儲在下一個字中。