Objective-Cの構造

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

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

  • Title
  • Author
  • Subject
  • ブックID

構造の定義

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

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

ザ・ structure tagオプションであり、各メンバー定義はintiなどの通常の変数定義です。またはfloatf; またはその他の有効な変数定義。構造体の定義の最後、最後のセミコロンの前に、1つ以上の構造体変数を指定できますが、これはオプションです。これがあなたが本の構造を宣言する方法です-

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

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

構造体の任意のメンバーにアクセスするには、 member access operator (.)。メンバーアクセス演算子は、構造体変数名とアクセスする構造体メンバーの間のピリオドとしてコード化されます。あなたは使用します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

ビットフィールド

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

  • いくつかのオブジェクトをマシンワードにパックします。たとえば、1ビットフラグを圧縮できます。

  • 外部ファイル形式の読み取り-非標準のファイル形式を読み込むことができます。たとえば、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には6つのメンバーが含まれています。4つの1ビットフラグf1..f3、4ビットタイプおよび9ビットmy_intです。

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