Objective-C陣列可定義包含多個相同型別的資料項的變數型別,但結構體是Objective-C程式設計中的另一個使用者定義資料型別,它可組合不同型別的資料項。
結構體用於表示記錄,假設要圖書館中跟蹤書籍資訊。可能希望跟蹤每本書的以下屬性 -
要定義結構體,必須使用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;
要存取結構的任何成員,使用成員存取運算子(.
)。成員存取運算子是結構體變數名稱和要存取結構體成員之間使用句點(.
)連線。使用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 = @"Yiibai";
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 : Yiibai
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
可以將結構體作為函式引數傳遞,與傳遞任何其他變數或指標的方式非常相似。將以與上面範例中存取的方式類似,存取結構體變數如下程式碼 -
#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 = @"Yiibai";
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 : Yiibai
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
按照與定義指向變數的指標相似的方式來定義指向結構體的指標,如下所示 -
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
位欄位允許在結構中打包資料。當記憶體或資料儲存非常寶貴時,這尤其有用。 下面是一個典型例子 -
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
位型別和9
位my_int
。
Objective-C盡可能緊湊地自動打包上述位欄位,前提是欄位的最大長度小於或等於計算機的整數位長。 如果不是這種情況,那麼一些編譯器可能允許欄位的儲存器重疊,而其他編譯器將下一個欄位儲存在下一個字中。