Создание базового калькулятора печати в Objective-C с использованием вложенного переключателя в цикле while - PullRequest
0 голосов
/ 27 июля 2011

В настоящее время я учусь на втором курсе по компьютерным наукам в колледже, и все, что я узнал до сих пор в области программирования, - это базовые знания Python и Java, и это действительно так. Так как у меня есть Mac, я решил попробовать Objective-C и купил книгу от Amazon, чтобы помочь мне в этом (книга «Программирование в Objective-C, третье издание» Стивена Кочана. Это отличная книга для меня, так как я все еще новичок в программировании в целом!)

Одним из упражнений, которые моя книга рекомендует для меня, является создание простого калькулятора печати с использованием операторов переключения и логических переменных, которые я выучил в предыдущей главе. Программа предназначена для выполнения, как показано ниже:

Добро пожаловать в PrintCalc! Доступны следующие функции: +, -, *, /, S и E. Тип в виде [целое число] [оператор].

Мой ввод: 100 S

Обратная связь: = 100

Мой ввод: 50 +

Обратная связь: = 150

Мой ввод: 2 /

Обратная связь: = 75

Мой ввод: 0 E

Обратная связь: = 75

Затем программа должна завершиться.

Оператор S установит аккумулятор, который определен в разделах @interface и @implementation моей программы. Оператор E всегда будет принимать 0 в качестве числового ввода, но число на самом деле не имеет значения. E просто завершает программу.

Вот код моей программы. Я собираюсь показать только основной метод здесь и раздел реализации @ позже, но если вы хотите увидеть раздел @interface, я с удовольствием. Кроме того, вы можете игнорировать некоторые из моих комментариев, поскольку многие из них, вероятно, не будут иметь большого смысла!

int main (int argc, char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc]init];

//Define the variables to be used in the outermost scope of the program.
double thisNum;
char thisChar;
BOOL isFinished;
PrintCalc * CalcInstant = [[PrintCalc alloc]init];

NSLog(@"\nWelcome to PrintCalc! Available functions are +, -, *, /, S, and E. \nType in    the form of [integer] [operator].");

//Initialize the isFinished variable.
isFinished = false;

//This do-while loop should terminate with the falsification of the isFinished boolean.
do
{
    scanf (" %f %c", &thisNum, &thisChar);
    //Use a 'switch' statement to make multiple decisions and meet multiple conditions.
    switch (thisChar)
    {
        case 'S':
            [CalcInstant setAccumulator: thisNum];
            NSLog(@"= %f", [CalcInstant accumulator]);
            break;

        case '+':
            [CalcInstant add: thisNum];
            NSLog(@"= %f", [CalcInstant accumulator]);
            break;

        case '-':
            [CalcInstant subtract: thisNum];
            NSLog(@"= %f", [CalcInstant accumulator]);
            break;

        case '*':
            [CalcInstant multiply: thisNum];
            NSLog(@"= %f", [CalcInstant accumulator]);
            break;

        case '/':
            [CalcInstant divide: thisNum];
            NSLog(@"= %f", [CalcInstant accumulator]);
            break;

        case 'E':
            isFinished = true;
            break;

        //This next case is a 'hidden' operator that only the programmer knows about. Displays the value of the thisNum variable.
        case '@':
            NSLog(@">>> %f", thisNum);
            break;

        default:
            NSLog(@"Bad operator and/or not a real number.");
            break;
    }
}
while (isFinished != true);

NSLog(@"= %g", [CalcInstant accumulator]);

[CalcInstant release];
[pool drain];

return 0;
}

Существует две проблемы с моей программой (о которых я знаю ...). Прежде всего, программа изначально содержала цикл while, а не цикл do-while. По какой-то странной причине цикл do-while работает отлично, тогда как, если бы я использовал цикл while, программа никогда бы не вошла в цикл. Кто-нибудь знает, почему это произошло?

Моя вторая проблема - компьютер, похоже, не распознает переменную thisNum. Причина, по которой я создал оператор «@» в операторе switch, заключалась в том, чтобы проверить, будет ли компьютер считать указанное число. По какой-то странной причине это не так, хотя мой код в разделе @implementation, кажется, работает нормально, если я «жестко кодирую» операции в самой программе, а не использую пользовательский ввод, чтобы спросить, какую операцию следует выполнить. (Например: я просто набираю [CalcInstant add: 50], чтобы компьютер добавил 50 к аккумулятору.) Вот раздел @implementation.

@implementation PrintCalc

-(void) setAccumulator: (double) value
{
    accumulator = value;
}

-(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

Программа будет запускаться и завершаться нормально, даже с использованием оператора 'E', что означает, что операторы читают очень хорошо. Однако, когда я использую свой специальный оператор «@» со значением 100, компьютер возвращает «0,000000» в качестве значения thisNum, что неверно.

Это вполне может быть ошибкой новичка, но я учусь! Пожалуйста, не будьте слишком резкими со мной, но конструктивная критика всегда приветствуется! Большое спасибо за любую помощь, которую вы можете оказать!

1 Ответ

2 голосов
/ 27 июля 2011

Это очень распространенная проблема при использовании функции scanf и удваивается. Фактически, если вы воспользуетесь этими двумя поисковыми запросами, вы получите удивительно длинный список совпадений с людьми, имеющими ту же проблему. По сути, вы хотите использовать спецификатор формата %lf для чтения пар, используя scanf, а не просто %f. Я изменил это и проверил ваш код, и он работает очень хорошо.

Я также переместил оператор while обратно в начало вашего цикла, и он отлично работает. Я подозреваю, что вы внесли некоторые другие изменения между тем, когда вы впервые столкнулись с этой проблемой, и теперь, потому что все работает как ожидалось.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...