@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, char argv[]) { NSAutoreleasePool pool = [[NSAutoreleasePool alloc] init]; double value 1, value2; char operator; Calculator deskCalc = [[Calculator alloc] init]; NSLog (@"Type in your expression."); scant («%lf %c %lf», &value1, &operator, &value2); [deskCalc setAccumulator: valuel]; if ( operator == ) [deskCalc add: value2]; else if ( operator == ) [deskCalc subtract: value2]; else if ( operator =='') [deskCalc multiply: value2]; else if ( operator == '/') [deskCalc divide: value2]; NSLog (@"%.2f", [deskCalc accumulator]); [deskCalc release]; [pool drain]; return 0; } Вывод программы 6.8 Type in your expression. (Введите ваше выражение) 123.5 + 59.3 182.80 Вывод программы 6.8 (повторный запуск) Type in your expression. 198.7/26 7.64 Вывод программы 6.8 (повторный запуск) Type in your expression. 89.3 2.5 223.25 При обращении к scant указывается, что должны быть считаны три значения в переменные valuel, operator и value2. Значение типа double можно прочитать с помощью символов формата %lf. Этот формат считывает значения в переменную valuel, которая является первым операндом выражения. Затем считывается оператор. Поскольку оператор представляется символом или 7 ), а не числом, он читается в символьную переменную operator. Символы формата %с указывают, что нужно прочитать с терминала следующий символ. Пробелы внутри строки формата указывают, что при вводе допускается любое число пробелов. Это позволяет при вводе значений отделять операнды от оператора. После считывания двух значений и оператора программа сохраняет первое значение в сумматоре (accumulator) калькулятора. Затем значение operator сравнивается с четырьмя возможными операторами. Если найдено допустимое со ответствие, калькулятору передается сообщение для выполнения операции. В последней строке NSLog значение accumulator считывается для вывода. После этого выполнение программы завершается. Здесь необходимо сказать несколько слов о законченности программы. Хотя приведенная программа выполняет поставленную задачу, ее нельзя назвать законченной, поскольку в ней не учитываются ошибки пользователя. Например, что произойдет, если пользователь ошибся и ввел ? в качестве имени оператора? Программа просто пройдет через оператор if, и на терминале не появится никаких ошибок, уведомляющих пользователя, что он ввел недопустимое выражение. Еще один неучтенный случай это ввод пользователем нулевого значения делителя в операции деления. Программа должна проверять этот случай. Определение ситуаций, при которых возможен отказ программы или получение нежелательных результатов, и принятие предупредительных мер обязательная часть разработки надежных программ. Программа 6.8А является модифицированной версией программы 6.8. В ней учитываются деление на нуль и ввод неизвестного оператора. Программа 6.8А // Программа вычисления простых выражений в форме // число оператор число import
// Здесь нужно вставить секции interface и implementation // для класса Calculator int main (int argc, char argv[]) NSAutoreleasePool pool = [[NSAutoreleasePool alloc] init]; double value 1, value2; char operator; Calculator deskCalc = [[Calculator alloc] init]; NSLog (@"Type in your expression."); scant («%lf %c %lf», &value1, &operator, &value2); [deskCalc setAccumulator: valuel]; if ( operator =='+') [deskCalc add: value2]; else if ( operator =='-') [deskCalc subtract: value2]; else if ( operator =='
) [deskCalc multiply: value2]; else if ( operator == ' / ' ) if ( value2 == 0 ) NSLog (@"Division by zero."); else [deskCalc divide: value2]; else NSLog (@"Unknown operator."); NSLog (@"%.2f", [deskCalc accumulator]); [deskCalc release]; [pool drain]; return 0; } Вывод программы 6.8A Type in your expression. (Введите ваше выражение) 123.5 + 59.3 182.80 Вывод программы 6.8А (повторный запуск) Type in your expression. 198.7/0 Division by zero. (Деление на нуль) 198.7 Вывод программы 6.8А (повторный запуск) Type in your expression. 125 $28 Unknown operator. (Неизвестный оператор) 125 Если введен оператор деления (слэш), то проверяется, не равно ли нулю значения value2. Если равно, выводится соответствующее сообщение; если нет выполняется операция деления и выводятся результаты. Обратите внимание, как в данном случае вложены оператор if и предложения else. Предложение else в конце программы позволяет «уловить» любые непредусмотренные случаи. Поэтому любое значение переменной operator, которое не совпадает с одним из четырех символов вычислений, приводит к выполнению предложения else, и на терминал выводится сообщение «Unknown operator» (Неизвестный оператор). Более удобный способ обработки ситуации деления на ноль это выполнение проверки в методе, который работает с операцией деления. Метод divide: можно модифипировать следующим образом. -(void) divide: (double) value { if (value != 0.0) accumulator /= value; else { NSLog ((@"Division by zero."); accumulator = 99999999.; ) } Для ненулевого значения выполняется деление; для нулевого выводится сообщ ен и е, и переменной accumulator п ри сваи вается значение 99999999. Это произвольно выбранное значение; можно было присвоить значение 0 или задать специальную переменную, указывающую состояние ошибки. Лучше включать обработку особых ситуаций в сам метод, чем полагаться на предусмотрительность программиста при использовании метода. Оператор switch