Struktury celu-C
Tablice Objective-C pozwalają zdefiniować typ zmiennych, które mogą zawierać kilka elementów danych tego samego rodzaju, ale structure jest kolejnym typem danych zdefiniowanym przez użytkownika dostępnym w programowaniu Objective-C, który umożliwia łączenie elementów danych różnego rodzaju.
Struktury są używane do reprezentowania rekordów. Załóżmy, że chcesz śledzić swoje książki w bibliotece. Możesz chcieć śledzić następujące atrybuty dotyczące każdej książki -
- Title
- Author
- Subject
- Identyfikator książki
Definiowanie struktury
Aby zdefiniować strukturę, musisz użyć structkomunikat. Instrukcja struct definiuje nowy typ danych z więcej niż jednym składnikiem programu. Format instrukcji struct pokazano poniżej -
struct [structure tag] {
member definition;
member definition;
...
member definition;
} [one or more structure variables];
Plik structure tagjest opcjonalna, a każda definicja elementu jest normalną definicją zmiennej, taką jak int i; lub float f; lub inną prawidłową definicję zmiennej. Na końcu definicji struktury, przed ostatnim średnikiem, można określić jedną lub więcej zmiennych strukturalnych, ale jest to opcjonalne. Oto sposób, w jaki można zadeklarować strukturę książki -
struct Books {
NSString *title;
NSString *author;
NSString *subject;
int book_id;
} book;
Dostęp do członków struktury
Aby uzyskać dostęp do dowolnego elementu członkowskiego struktury, używamy rozszerzenia member access operator (.). Operator dostępu do elementu jest zakodowany jako okres między nazwą zmiennej strukturalnej a elementem struktury, do którego chcemy uzyskać dostęp. Używałbyśstructsłowo kluczowe do definiowania zmiennych typu konstrukcji. Poniżej znajduje się przykład wyjaśniający użycie struktury -
#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;
}
Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -
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
Struktury jako argumenty funkcji
Możesz przekazać strukturę jako argument funkcji w bardzo podobny sposób, jak przekazujesz dowolną inną zmienną lub wskaźnik. Dostęp do zmiennych strukturalnych uzyskasz w podobny sposób, jak w powyższym przykładzie -
#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;
}
Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -
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
Wskaźniki do struktur
Możesz zdefiniować wskaźniki do struktur w bardzo podobny sposób, jak definiujesz wskaźnik do dowolnej innej zmiennej w następujący sposób -
struct Books *struct_pointer;
Teraz możesz przechowywać adres zmiennej strukturalnej w zdefiniowanej powyżej zmiennej wskaźnikowej. Aby znaleźć adres zmiennej strukturalnej, umieść operator & przed nazwą struktury w następujący sposób -
struct_pointer = &Book1;
Aby uzyskać dostęp do elementów struktury za pomocą wskaźnika do tej struktury, należy użyć operatora -> w następujący sposób -
struct_pointer->title;
Napiszmy ponownie powyższy przykład za pomocą wskaźnika struktury, mam nadzieję, że będzie to łatwe do zrozumienia koncepcji -
#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;
}
Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -
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
Pola bitowe
Pola bitowe umożliwiają upakowanie danych w strukturę. Jest to szczególnie przydatne, gdy cenna jest pamięć lub przechowywanie danych. Typowe przykłady -
Pakowanie kilku obiektów w słowo maszynowe. np. flagi 1-bitowe mogą być kompaktowane.
Odczytywanie zewnętrznych formatów plików - można wczytać niestandardowe formaty plików. Np. 9-bitowe liczby całkowite.
Objective-C pozwala nam to zrobić w definicji struktury poprzez umieszczenie: długości bitu po zmiennej. Na przykład -
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;
Tutaj spakowany_strukt zawiera 6 elementów: Cztery 1-bitowe flagi f1..f3, 4-bitowy typ i 9-bitowy my_int.
Objective-C automatycznie pakuje powyższe pola bitowe tak kompaktowo, jak to tylko możliwe, pod warunkiem, że maksymalna długość pola jest mniejsza lub równa całkowitej długości słowa komputera. Jeśli tak nie jest, niektóre kompilatory mogą pozwolić na nakładanie się pamięci dla pól, podczas gdy inne będą przechowywać następne pole w następnym słowie.