Программирование на Objective-C 2.0
Шрифт:
Выполните расширение класса Fraction, добавив методы, которые подчиняются неформальному протоколу NSComparisonMethods, описанному з этой главе. Напишите реализацию первых шести методов из этого протокола (isEqualTo:, isLessThanOrEqualTo:, isLessThan:, isGreaterThanOrEquaHo:, isGreaterThan:,isNotEqualTo:) и выполните их тестирование.
Функции sin ,cos и tan {) включены в стандартную библиотеку Standard Library (как и scant ). Эти функции объявлены в header-файле , который вы должны импортировать в программу с помощью строки #import <math.h> Эти функции можно использовать для вычисления синуса, косинуса и тангенса аргумента типа double, выраженного в радианах. Возвращаемый результат является значением с плавающей точкой
– (double) sin; -(double) cos; -(double) tan;
Напишите секцию implementation для Square и выполните тестирование программы для проверки ее методов, используя описание составных объектов из этой главы и следующую секцию interface, @interface Square: NSObject { Rectangle *rect; } -(Square*) initWithSide: (int) s; -(void) setSide: (int) s; -(int) side; -(int) area; -(int) perimeter; -(void) dealloc; // Замещающий метод для освобождения памяти объекта типа Rectangle @end
Глава 12. Препроцессор
Препроцессор содержит средства, упрощающие чтение, разработку и встраивание программ в различные системы. Препроцессор позволяет настроить язык Objective-C в соответствии с конкретным программным приложением или вашим стилем программирования.
Препроцессор — это составная часть процесса компиляции Objective-C. Он распознает специальные операторы и обрабатывает их, прежде чем будет выполнен анализ самой программы. Операторы препроцессора идентифицируются знаком «решетка» (#), который должен быть первым символом строки, отличным от пробела. Синтаксис операторов препроцессора несколько отличаюется от обычных операторов Objective-C. Мы начнем с описания оператора #define. 12.1. Оператор # define
Оператор #define позволяет присваивать символические имена программным константам. Оператор препроцессора #define TRUE 1
определяет имя TRUE и делает его эквивалентным значению 1. Затем имя TRUE можно использовать в любом месте программы, где могла бы использоваться константа 1. Там, где появляется это имя, препроцессор автоматически подставляет вместо него значение 1. Например, следующий оператор Objective-C использует определенное имя TRUE. gameOver = TRUE;
Этот оператор присваивает значение TRUE переменной gameOver. Вам не обязательно помнить, какое конкретное значение вы определили для TRUE. Приведенный выше оператор будет присваивать 1 переменной gameOver. Оператор препроцессора #define FALSE О
определяет имя FALSE и делает его эквивалентным значению 0. Например, оператор gameOver = FALSE;
присваивает значение FALSE переменной gameOver, а оператор if ( gameOver == FALSE)
сравнивает значение gameOver с определенным значением FALSE.
Определенное таким образом имя не является переменной, поэтому вы не можете присвоить ему значение, если результатом подстановки значения не янляется переменная. Если в программе используется определенное имя, препроцессор автоматически подставляет то, что представлено в правой части оператора «define. Это аналогично операции поиска и замены втекстозом редакторе; в данном случае препроцессор заменяет все экземпляры определенного имени соответствующим текстом.
Отметим, что оператор «define имеет специальный синтаксис: для присваивания TRUE значения 1 не используется знак равенства. Кроме того, в конце оператора нет точки с запятой.
Операторы «define часто помещают ближе к началу программы, после операторов «import или «include, хотя они могут присутствовать в любом месте программы. Однако имя должно быть определено до того, как оно будет использовано. Определенные таким образом
имена отличаются по своему поведению от переменных: не существует такого понятия, как локальный «define». После определения имени его можно использовать в любом месте программы. Большинство программистов помещают операторы define в header-файлы (*.h), чтобы использовать их в нескольких исходных файлах.В следующем примере напишем два метода для поиска площади и длины окружности объекта типа Circle. Поскольку в обоих методах требуется использовать константу, значение которой трудно запомнить, имеет смысл определить значение этой константы в начале программы и затем применять его в каждом методе.
Поэтому мы можем включить в программу следующую строку: #define PI 3.141592654
Теперь эту константу можно использовать в обоих методах класса Circle (в предположении, что класс Circle содержит переменную экземпляра с именем radius). -(double) area { return PI * radius * radius; } -(double) circumference { return 2.0 * PI * radius; }
Назначение константы для символического имени освобождает вас от необходимости помнить значение константы. Кроме того, если потребуется изменить значение этой константы, то это нужно будет сделать только в одном месте программы: в операторе #define. В противном вам придется выполнить поиск по всей программе и явно изменить значение константы.
Во всех приведенных примерах операторов define использовались прописные буквы (TRUE, FALSE и PI). Это было сделано, чтобы визуально отличить определенное значение от переменной. Некоторые программисты записывают все определенные имена прописными буквами, чтобы сразу различать, что перед ними: переменную, объект, имя класса или определенное имя. Перед определенным именем принято ставить букву к. В этом случае прописными буквами обозначаются не все символы, например, kMaximumValues и kSignificantDigits.
Применение определенного имени для значения константы упрощает расширение программы. Для массивов вместо конкретного указания размера массива, который нужно выделить в памяти, можно определить нужное значение: #define МAXIМUM_DATA_VALUES 1000
Теперь на этом определенном значении можно основывать все ссылки на размер массива (например, чтобы выделить место для этого массива в памяти) и допустимые индексные значения.
Кроме того, если профамма использует MAXIMUM DATA VALUES во всех случаях, где нужно указать размер массива, то чтобы изменить размер массива, достаточно изменить только это определение. Более сложные типы определений
Определение имени может включать не только простое константное значение. Это может быть и выражение и почти все, что можно предположить!
Ниже имя TW0_PI определяется как произведение 2.0 на 3.141592654: #define 7W0_PI 2.0 * 3.141592654
После этого определенное имя можно использовать в любом месте программы, где требуется выражение 2.0 * 3.141592654. Например, оператор return в методе circumference из предыдущего примера можно заменить оператором return TWO_PI * radius;
Если в профамме на Objective-C встречается определенное имя, то все, что находится справа от этого определенного имени в операторе «define, подставляется вместо этого имени. Так, если препроцессор встречает имя TW0_PI в приведенном выше операторе return, он подставляет вместо этого имени то, что находится справа от этого имени в операторе «define, то есть 2.0 * 3.141592654.
Теперь вы понимаете, почему оператор #define нельзя закончить точкой с запятой. Если вы сделаете это, точка с запятой будет подставлена в том месте, где встретится соответствующее определенное имя. Если определить PI с помощью оператора #define PI 3.141592654;
и затем написать return 2.0 * PI * r;
препроцессор заменит этот экземпляр определенного имени PI на 3.141592654;.
Тогда после подстановки компилятору нужно будет обработать оператор return 2.0*3.141592654; * г;