Программирование на Objective-C 2.0
Шрифт:
Если значение целой переменной присваивается переменной с плавающей точкой, это не вызывает какого-либо изменения в значении числа; система просто преобразует это значение и сохраняет его в переменной с плавающей точкой. Во второй строке вывода программы показано, что значение \2 (-150) правильно преобразовано и сохранено в переменной f1 типа float.
В следующих двух строках вывода программы показаны две ситуации, о ко-торых нужно помнить при формировании арифметических выражений. В первом случае действует целочисленная арифметика, о которой мы говорили в пре-дыдущем разделе. Если два операнда выражения являются целыми (это относится и к целым переменным с модераторами short, unsigned и long), то операция выполняется по правилам целочисленной арифметики. Поэтому любая дробная часть, полученная в операции деления, отбрасывается,
Следующее деление применяется к целой переменной и константе с плава-ющей точкой. Любая операция, выполняемая с двумя значениями в Objective- С, выполняется как операция с плавающей точкой, если хотя бы одно из значений является переменной или константой с плавающей точкой. Поэтому при делении значения i2 на 100.0 система выполняет деление с плавающей точкой и дает результат -1.5, который присваивается переменной типа f1 float. Оператор приведения типа
При объявлении и определении методов для объявления типов возвращаемого значения и аргументов тип включается в круглые скобки. Внутри выражений этот способ применяется для другой цели.
В последней операции деления программы 4.5 появляется оператор приве-дения типа: f2 = (float) i2 / 100; // оператор приведения типа
В данном случае для вычисления выражения оператор приведения типа ис-пользуется для преобразования значения переменной i2 в тип float. Это оператор не влияет на значение переменной i2; это унарный оператор. Выражение (float) а не влияет на значение а — аналогично выражению -а.
Оператор приведения типа имеет более высокий приоритет, чем все ариф-метические операторы, за исключением унарных операций «плюс» и «минус». И, конечно, вы можете использовать в выражении круглые скобки, чтобы вы-числения выполнялись в нужном порядке.
В этом примере выражение (int) 29.55 + (int) 21.99
вычисляется в Objective-C как 29 + 21
поскольку приведение значения с плавающей точкой к целому типу приводит к отбрасыванию дробной части. Выражение (float) 6 / (float) 4
дает значение 1.5, как и в следующем выражении: (float) 6/4
Оператор приведения типа часто используется для принудительного приве-дения объекта, имеющего обобщенный тип id, к объекту определенного класса. Например, в следующих строках выполняется преобразование значения пере-менной myNumber типа id к объекту класса Fraction: id myNumber; Fraction *myFraction; myFraction = (Fraction *) myNumber;
Результат этого преобразования присваивается переменной myFraction типа Fraction. 4.3. Операторы присваивания
Язык Objective-C позволяет объединять арифметические операторы с оператором присваивания в обобщенном формате ор=
В этом формате ор - любой из арифметических операторов, включая +, *, / или %. Кроме того, ор может быть любым из битовых операторов для смещения и маскирования, которые описываются ниже.
Рассмотрим строку count += 10;
Оператор «плюс равно» += добавляет выражение, находящееся справа от этого оператора, к переменной, находящейся слева от оператора, и сохраняет результат в этой переменной. Таким образом, приведенная выше строка экви-валентна следующей строке: count = count + 10;
В следующем выражении используется оператор «минус равно» для вычи-тания 5 из значения переменной counter: counter -= 5
Это эквивалентно выражению counter = counter - 5
А теперь чуть более сложное выражение: а /= b + с
Выполняется деление а на то, что находится справа от знака равенства (сумму b и с), и сохранение результата в а. Сначала выполняется сложение, поскольку оператор сложения имеет более высокий приоритет, чем оператор присваивания. Все операторы, кроме точкой, имеют более высокий приоритет, чем операторы присваивания, которые имеют одинаковый приоритет.
Это выражение эквивалентно следующему: а = а / (b + с)
Операторы присваивания используются потрем причинам. Во-первых, про-грамму проще писать: то, что находится слева от оператора присваивания, не нужно повторять с правой стороны. Во-вторых, результирующее выражение проще читать. В третьих, программы могут выполняться быстрее, поскольку компилятор иногда генерирует более
короткий код для вычисления выражения. 4.4. Класс CalculatorТеперь можно определить новый класс. Мы создадим класс Calculator для сложения, умножения, вычитания и деления чисел. Как и обычный калькулятор, он должен следить за промежуточной суммой, которую называют накапливающим сумматором, или просто сумматором (accumulator). Поэтому соответствующие методы должны позволять вам задавать для сумматора определенное значение, выполнять его сброс (задавать равным нулю) и считывать значение, когда закончатся вычисления. В программе 4.6 содержится определение этого класса и тестовая программа. // Реализация класса Calculator #import <Foundation/Foundation.h> @interface Calculator: NSObject { double accumulator; } // методы для сумматора (accumulator) -(void) setAccumulator: (double) value; -(void) clear; -(double) accumulator; // арифметические методы -(void) add: (double) value; -(void) subtract: (double) value; -(void) multiply: (double) value; -(void) divide: (double) value; @end @implementation Calculator -(void) setAccumulator: (double) value { accumulator = value; ) -(void) clear { accumulator = 0; } -(double) accumulator { return accumulator; } -(void) add: (double) value { accumulator += value; } -(void) subtract: (double) value { accumulator -= value; } -(void) multiply: (double) value { accumulator *= value; } -(void) divide: (double) value { accumulator /= value; } @end int main (int argc, cfiar *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Calculator *deskCalc; deskCalc = [[Calculator alloc] init]; [deskCalc clear]; [deskCalc setAccumulator: 100.0]; [deskCalc add: 200.]; [deskCalc divide: 15.0]; [deskCalc subtract: 10.0]; [deskCalc multiply: 5]; NSLog (@"The result is %g", [deskCalc accumulator]); [deskCalc release]; [pool drain]; return 0; }
Вывод программы 4.6 The result is 50
Класс Calculator имеет только одну переменную экземпляра типа double, со-держащую значение сумматора. Сами определения методов достаточно просты. Обратите внимание на сообщение, которое вызывает метод multiply: [deskCalc multiply: 5];
Этому методу передается целый аргумент, хотя в методе предполагается значение типа double. Здесь нет никакой проблемы, поскольку числовые аргументы, передаваемые методам, автоматически преобразуются в соответствующий предполагаемый тип. Метод multiply: предполагает значение типа double, поэтом при вызове функции целое значение 5 автоматически преобразуется в значение с плавающей точкой двойной точности. Здесь преобразование происходит автоматически, по практика программирования все же рекомендует задавать соответствующие типы аргументов при вызове методов.
В отличие от класса Fraction, где можно работать со многими дробями, в пашей программе, возможно, потребуется работа только с одним объектом Calculator. Имеет смысл определить новый класс, чтобы упростить работу с этим объектом. В какой-то момент вам захочется добавить графический интерфейс к своему калькулятору, чтобы пользователь мог реально щелкать кнопками на экране, как в широко распространенном приложении calculator. 4.5. Битовые операторы
Некоторые операторы в языке Objective-C работают с определенными битами внутри числа. Эти операторы представлены в таблице 4.2.
Табл. 4.2. Битовые операторы Символ Операция & Побитовое И | Побитовое включающее ИЛИ ^ Побитовое исключающее ИЛИ ~ Дополнение до единицы << Сдвиг влево >> Сдвиг вправо
Все операторы из таблицы 4.2, за исключением оператора дополнения до единицы (~), являются бинарными операторами, то есть предполагают два опе-ранда. Битовые операции можно выполнять с любым типом целого значения, но нельзя выполнять для значений с плавающей точкой. Побитовый оператор И
Если два значения связаны оператором И (&), то двоичные представления этих значений сравниваются бит за битом. Если какой-либо бит первого значения равен 1 и соответствующий бит второго значения равен 1, то соответствующий бит результата равен 1; во всех остальных случаях результат равен 0. Пусть b1 и b2 представляют соответствующие биты в двух операндах. В следующей таблице, которая называется таблицей истинности (truth table), представлены результаты операции И для всех возможных значений b1 и b2. b1 b2 b1 & b2 0 0 0 0 1 0 1 0 0 1 1 1