[Objective-C语言教程]结构体(17)
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尽可能紧凑地自动打包上述位字段,前提是字段的最大长度小于或等于计算机的整数字长。 如果不是这种情况,那么一些编译器可能允许字段的存储器重叠,而其他编译器将下一个字段存储在下一个字中。