位置:首页 > 高级语言 > Objective-C在线教程 > Objective-C struct/结构

Objective-C struct/结构

Objective-C 数组允许您定义的变量的类型,可容纳几个数据项的同类,但结构是另一个用户定义的数据类型,它允许将不同种类的数据项在Objective-C编程。

结构被用来代表一个记录,假设想跟踪书籍在图书馆。可能要跟踪有关每本书的下列属性:

  • 标题

  • 作者

  • 主题

  • 图书 ID

定义一个结构

要定义一个结构,必须使用结构语句。结构语句定义了一个新的数据类型,与一个以上的成员为程序。结构语句的格式是这样的:

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

结构变量是可选的,每个成员的定义是一个正常的变量定义,如int;或float f;或任何其他有效的变量定义。结构的定义在结束之前,最后是分号,可以指定一个或多个结构变量,但它是可选的。这里有一种方法,可能声明书的结构:

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;        /* 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 : %@
", Book1.title);
   NSLog(@"Book 1 author : %@
", Book1.author);
   NSLog(@"Book 1 subject : %@
", Book1.subject);
   NSLog(@"Book 1 book_id : %d
", Book1.book_id);

   /* print Book2 info */
   NSLog(@"Book 2 title : %@
", Book2.title);
   NSLog(@"Book 2 author : %@
", Book2.author);
   NSLog(@"Book 2 subject : %@
", Book2.subject);
   NSLog(@"Book 2 book_id : %d
", 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 : %@
", book.title);
   NSLog(@"Book author : %@
", book.author);
   NSLog(@"Book subject : %@
", book.subject);
   NSLog(@"Book book_id : %d
", 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_yiibaier;

现在可以存储结构体变量的地址,在上述定义的变量的指针。为了找到一个结构变量的地址,前放置&运算结构的名称如下:

struct_yiibaier = &Book1;

要访问的成员的结构,使用该结构的一个指针,必须使用 -> 运算符如下:

struct_yiibaier->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 : %@
", book->title);
   NSLog(@"Book author : %@
", book->author);
   NSLog(@"Book subject : %@
", book->subject);
   NSLog(@"Book book_id : %d
", 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语言可以让我们做到这一点,通过把结构定义:后位长度变量。例如:

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的自动包装上述的位字段尽可能紧凑的,前提是该字段的最大长度是小于或等于计算机的字长的整数。如果不是这种情况,那么某些编译器可能允许重叠,而其他的字段存储器存储下一个字段中的下一个字。