Язык С предлагает только несколько простых собственных типов данных. Каким же образом создавать более сложные типы данных? Существуют три способа: структуры, указатели и массивы. Структуры и указатели играют огромную роль при программировании для IOS. Массивы языка программирования С требуются гораздо реже, потому что Objective-C имеет свой собственный объектный тип NSArray.

Структура в языке С (K&R 6.1) представляет собой составной тип данных: она объединяет несколько типов данных в один, который рассматривается как единая сущность. Элементы, составляющие структуру, имеют имена, и к ним можно обращаться по этим именам с помощью записи с точкой. В интерфейсе API системы IOS предусмотрено множество структур, обычно вместе с функциями для работы с этими структурами.

Например, в документации IOS говорится, что структура CGPoint определена следующим образом:

struct CGPoint {
CGFloat х;
CGFloat у;
};
typedef struct CGPoint CGPoint;

Вспомним, что объект класса CGFloat представляет собой не что иное, как число с плавающей точкой, так что данный составной тип объединяет два простых встроенных типа данных; по сути, структура CGPoint имеет две части типа CGFloat с именами х и у. (Странно выглядящая последняя строка фрагмента кода просто позволяет использовать краткое имя типа данных CGPoint вместо более длинного struct CGPoint.) Таким образом, мы можем записать

CGPoint myPoint;
myPoint.x = 4.3;
myPoint.y = 7.1;

Так же как мы можем выполнить присваивание myPoin t. х, чтобы установить значение этой части структуры, мы можем использовать имя myPoint. х, чтобы получить значение этой части структуры. Все выглядит так, как если бы myPoint. х было именем переменной.

Более того, элемент структуры сам может быть структурой, и запись с точкой может образовывать цепочки. Для иллюстрации рассмотрим еще одну структуру iOS, CGSize:

struct CGSize {
CGFloat width;
CGFloat height;
};
typedef struct CGSize CGSize;

Объединим структуры CGPoint и CGSize и получим структуру CGRect:

struct CGRect {
CGPoint origin;
CGSize size;
} ;
typedef struct CGRect CGRect;

Теперь предположим, что у нас есть уже инициализированная переменная типа CGRect с именем rnyRect. Тогда rnyRect. origin представляет собой структуру CGPoint, а rnyRect. origin. х - структуру CGFloat. Аналогично rnyRect. size представляет собой структуру CGSize, а rnyRect. size. width - структуру CGFloat. Можно непосредственно изменить одну только часть width структуры CGRect, записав код наподобие

myRect.size.width = 8.6;

Вместо инициализации структуры путем присваивания значения каждому из ее элементов можно инициализировать ее во время объявления, указав одновременно значения для всех ее элементов в фигурных скобках и разделив их запятыми:

CGPoint myPoint = { 4.3, 7.1 };
CGRect myRect = { myPoint, (10, 20} };

Вы не обязаны использовать инициализатор структуры только с помощью присваивания переменной соответствующего типа. Инициализатор можно использовать везде, где ожидается данная структура; но от вас может потребоваться использовать явное приведение к требуемому типу, чтобы пояснить компилятору, что означает выражение в фигурных скобках:

CGContextFillRect(con, (CGRect) {myPoint, (10, 20}});

В этом примере CGContextFillRect - это функция. О функциях я расскажу несколько позже в данной главе, а пока главное в примере - что-то, что идет после первой запятой, должно быть CGRect, так что здесь можно разместить инициализатор для типа CGRect, сопроводив его явным приведением к типу CGRect.


 

 

 

Добавить комментарий