Objective-c-structures

提供:Dev Guides
移動先:案内検索

Objective-Cの構造

Objective-C配列を使用すると、同じ種類の複数のデータ項目を保持できる変数のタイプを定義できますが、 structure は、Objective-Cプログラミングで使用できる別のユーザー定義データ型で、異なる種類のデータ項目を組み合わせることができます。

構造はレコードを表すために使用されます。図書館で本を追跡したいとします。 あなたは、各本に関する次の属性を追跡することができます-

  • タイトル
  • 著者
  • 件名
  • ブックID

構造の定義

構造を定義するには、 struct ステートメントを使用する必要があります。 structステートメントは、プログラムに複数のメンバーを持つ新しいデータ型を定義します。 構造体ステートメントの形式は以下に示されています-

struct [structure tag] {
   member definition;
   member definition;
   ...
   member definition;
} [one or more structure variables];
  • 構造タグ*はオプションであり、各メンバー定義はint iなどの通常の変数定義です。またはfloat f;または他の有効な変数定義。 構造の定義の最後で、最後のセミコロンの前に、1つ以上の構造変数を指定できますが、これはオプションです。 ここにあなたが本の構造を宣言する方法があります-
struct Books {
   NSString *title;
   NSString *author;
   NSString *subject;
   int   book_id;
} book;

構造体メンバーへのアクセス

構造体のメンバーにアクセスするには、* memberアクセス​​演算子(。)を使用します。 メンバーアクセス演算子は、構造変数名とアクセスする構造メンバーの間のピリオドとしてコーディングされます。 *struct キーワードを使用して、構造タイプの変数を定義します。 以下は、構造の使用法を説明する例です-

#import <Foundation/Foundation.h>

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

int main() {
   struct Books Book1;       /*Declare Book1 of type Book*/
   struct Books Book2;       /*Declare Book2 of type Book*/

  /*book 1 specification*/
   Book1.title = @"Objective-C Programming";
   Book1.author = @"Nuha Ali";
   Book1.subject = @"Objective-C Programming Tutorial";
   Book1.book_id = 6495407;

  /*book 2 specification*/
   Book2.title = @"Telecom Billing";
   Book2.author = @"Zara Ali";
   Book2.subject = @"Telecom Billing Tutorial";
   Book2.book_id = 6495700;

  /*print Book1 info*/
   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);

  /*print Book2 info*/
   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;
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

2013-09-14 04:20:07.947 demo[20591] Book 1 title : Objective-C Programming
2013-09-14 04:20:07.947 demo[20591] Book 1 author : Nuha Ali
2013-09-14 04:20:07.947 demo[20591] Book 1 subject : Objective-C Programming Tutorial
2013-09-14 04:20:07.947 demo[20591] Book 1 book_id : 6495407
2013-09-14 04:20:07.947 demo[20591] Book 2 title : Telecom Billing
2013-09-14 04:20:07.947 demo[20591] Book 2 author : Zara Ali
2013-09-14 04:20:07.947 demo[20591] Book 2 subject : Telecom Billing Tutorial
2013-09-14 04:20:07.947 demo[20591] Book 2 book_id : 6495700

関数の引数としての構造

他の変数またはポインターを渡すのと非常によく似た方法で、構造体を関数の引数として渡すことができます。 上記の例でアクセスしたのと同様の方法で構造変数にアクセスします-

#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;       /*Declare Book1 of type Book*/
   struct Books Book2;       /*Declare Book2 of type Book*/

  /*book 1 specification*/
   Book1.title = @"Objective-C Programming";
   Book1.author = @"Nuha Ali";
   Book1.subject = @"Objective-C Programming Tutorial";
   Book1.book_id = 6495407;

  /*book 2 specification*/
   Book2.title = @"Telecom Billing";
   Book2.author = @"Zara Ali";
   Book2.subject = @"Telecom Billing Tutorial";
   Book2.book_id = 6495700;

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

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

   return 0;
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

2013-09-14 04:34:45.725 demo[8060] Book title : Objective-C Programming
2013-09-14 04:34:45.725 demo[8060] Book author : Nuha Ali
2013-09-14 04:34:45.725 demo[8060] Book subject : Objective-C Programming Tutorial
2013-09-14 04:34:45.725 demo[8060] Book book_id : 6495407
2013-09-14 04:34:45.725 demo[8060] Book title : Telecom Billing
2013-09-14 04:34:45.725 demo[8060] Book author : Zara Ali
2013-09-14 04:34:45.725 demo[8060] Book subject : Telecom Billing Tutorial
2013-09-14 04:34:45.725 demo[8060] Book book_id : 6495700

構造体へのポインター

次のように他の変数へのポインタを定義するのと非常に似た方法で構造体へのポインタを定義できます-

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;       /*Declare Book1 of type Book*/
   struct Books Book2;       /*Declare Book2 of type Book*/

  /*book 1 specification*/
   Book1.title = @"Objective-C Programming";
   Book1.author = @"Nuha Ali";
   Book1.subject = @"Objective-C Programming Tutorial";
   Book1.book_id = 6495407;

  /*book 2 specification*/
   Book2.title = @"Telecom Billing";
   Book2.author = @"Zara Ali";
   Book2.subject = @"Telecom Billing Tutorial";
   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;
}

上記のコードをコンパイルして実行すると、次の結果が生成されます-

2013-09-14 04:38:13.942 demo[20745] Book title : Objective-C Programming
2013-09-14 04:38:13.942 demo[20745] Book author : Nuha Ali
2013-09-14 04:38:13.942 demo[20745] Book subject : Objective-C Programming Tutorial
2013-09-14 04:38:13.942 demo[20745] Book book_id : 6495407
2013-09-14 04:38:13.942 demo[20745] Book title : Telecom Billing
2013-09-14 04:38:13.942 demo[20745] Book author : Zara Ali
2013-09-14 04:38:13.942 demo[20745] Book subject : Telecom Billing Tutorial
2013-09-14 04:38:13.942 demo[20745] Book book_id : 6495700

ビットフィールド

ビットフィールドを使用すると、構造体にデータをパックできます。 これは、メモリまたはデータストレージが貴重な場合に特に便利です。 典型的な例-

  • 複数のオブジェクトを機械語にパックします。 e.g. 1ビットフラグは圧縮できます。
  • 外部ファイル形式の読み取り-非標準のファイル形式を読み取ることができます。 E.g. 9ビット整数。

Objective-Cでは、変数の後に:bit lengthを追加することにより、構造定義でこれを行うことができます。 たとえば-

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には、4つの1ビットフラグf1..f3、4ビットタイプ、9ビットmy_intの6つのメンバーが含まれています。

Objective-Cは、フィールドの最大長がコンピューターの整数ワード長以下である場合、上記のビットフィールドを可能な限りコンパクトに自動的にパックします。 そうでない場合、一部のコンパイラはフィールドのメモリオーバーラップを許可し、他のコンパイラは次の単語の次のフィールドを保存します。