1

Тема: Калькулятор

Допоможіть розібратися з ошибками в даному алгоритмі..

#include "stdafx.h"
#include "stdio.h"
#include "conio.h"
#include <stdlib.h>    /* для atof() */
 
  #define MAXOP   100    /* максимальний розмір операнда або оператора */
  #define NUMBER  '0'    /* сигналізувати, що номер знайдено */
  
  int getop(char []);
  void push(double);
  double pop(void);
main()
{
   int type;
      double op2;
      char s[MAXOP];
 
      while ((type = getop(s)) != EOF) {
          switch (type) {
          case NUMBER:
              push(atof(s));
              break;
          case '+':
              push(pop() + pop());
              break;
          case '*':
              push(pop() * pop());
              break;
          case '-':
              op2 = pop();
              push(pop() - op2);
              break;
          case '/':
              op2 = pop();
              if (op2 != 0.0)
                  push(pop() / op2);
              else
                  printf("error: zero divisor\n");
              break;
          case '\n':
              printf("\t%.8g\n", pop());
              break;
          default:
              printf("error: unknown command %s\n", s);
              break;
          }
      }
      getch();
    return 0;
}

2 Востаннє редагувалося User 298 (20.01.2013 14:11:31)

Re: Калькулятор

А які проблеми?

З.І: алгоритм варто би винести в окрему функцію, щоб у випадках ділення на нуль чи некоректного оператора зробити return або throw.

З.З.І: і масив s не зайве ініціалізувати нулями на початку.

3

Re: Калькулятор

Для того щоб навчитись користуватись цим калькулятором, необхідно прочитати розділи 4.1 - 4.4 книги КіР і просто весь код, що в них приводиться кинути в один файл. Ті функції, що ви описували в темі в прикладі і так передбачені, якщо буде необхідно розпізнавати знак мінус - напишете в нову тему, але якщо ви не прочитаєте оці розділи - то не зможете захистити курсовий проект, оскільки не будете знати як алгоритм працює.

4 Востаннє редагувалося LeoDevel (21.01.2013 12:55:51)

Re: Калькулятор

Форумчани прошу вашої допомоги..Як я вже писав передімною стояло завдання розробка програми у вигляді калькулятора інтерпритатор арефметичних вмразів заданого формату. В чому полягає моя проблема в мене  16 лютого весілля що потрибує реальної підготовки, а 4 лютого захист курсового по цій темі. Дійсно нема часу розбиратися функції, стеками. і т.п. В мене є алгоритм ну я неможу його завершети...Будь=ласка....
Алгоритм...

#include "stdafx.h"
#include "streal.h" // Інтерфейс"стек"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
 
 
//Прототип функції, реалізуючий команди калькулятора:
// Арефметичні операції
static void onAdd();
static void onSub();
static void onMul();
static void onDiv();
 
// Добавити число в стек(вх: текстовий запис числа)
static void onPush(const char* line);
 
// Обчислення матиматичних функцій
static void onSin();     // sin
static void onCos();     // cos
static void onExp();     // Экспонента
static void onLog();     // Натуральный логарифм
static void onSqrt();    // Квадратний корень
 
// Другие команды
static void onPop();     // Видалити вершину стеку
static void onClear();   // Очистити стек
static void display();   //Надрукуваим вершину стека
static void onShow();    // Надрукуваим содержимое стека
static void printHelp(); //Надрукуваим подсказку
 
int _tmain(int argc, _TCHAR* argv[])
{
    char line[256]; // Буфер для введення  строки
    int linelen;    // Довжина строки
 
    st_init(1024);  // Стек.почати роботу(1024)
                    //   1024 — макс. глубина стека
    printHelp();    // Надрукуваим підсказку
 
    while (true) {          // Цикл до нескінченості
        scanf("%s", line);      // ввести строку
        linelen = strlen(line); // довжина строки
        if (linelen == 0)
            continue;
 
   
        if (strcmp(line, "+") == 0) {
            onAdd();
        } else if (strcmp(line, "-") == 0) {
            onSub();
        } else if (strcmp(line, "*") == 0) {
            onMul();
        } else if (strcmp(line, "/") == 0) {
            onDiv();
        } else if (strcmp(line, "sin") == 0) {
            onSin();
        } else if (strcmp(line, "cos") == 0) {
            onCos();
        } else if (strcmp(line, "exp") == 0) {
            onExp();
        } else if (strcmp(line, "log") == 0) {
            onLog();
        } else if (strcmp(line, "sqrt") == 0) {
            onSqrt();
        } else if (strcmp(line, "=") == 0) {
            display();
        } else if (         // Если это число
            isdigit(line[0]) || (
                linelen > 1 &&
                (line[0] == '-' || line[0] == '+') && isdigit(line[1])
            )
        ) {
            onPush(line);   // Добавить число в стек
        } else if (strcmp(line, "pop") == 0) {
            onPop();
        } else if (strcmp(line, "clear") == 0) {
            onClear();
        } else if (strcmp(line, "show") == 0) {
            onShow();
        } else if (strcmp(line, "quit") == 0) {
            break;       // Закінчити работу
        } else {         // Неправильна команда =>
            printHelp(); //    Надрукувати підсказку
        }
    }
    return 0;
}
 
static void onAdd() {
    double y, x;
    if (st_size() < 2) {
        printf("Stack depth < 2.");
        return;
    }
    y = st_pop();
    x = st_pop();
    st_push(x + y);
    display();
}
 
static void onSub() {
    double y, x;
    if (st_size() < 2) {
        printf("Stack depth < 2.");
        return;
    }
    y = st_pop();
    x = st_pop();
    st_push(x - y);
    display();
}
 
static void onMul() {
    double y, x;
    if (st_size() < 2) {
        printf("Stack depth < 2.");
        return;
    }
    y = st_pop();
    x = st_pop();
    st_push(x * y);
    display();
}
 
static void onDiv() {
    double y, x;
    if (st_size() < 2) {
        printf("Stack depth < 2.");
        return;
    }
    y = st_pop();
    x = st_pop();
    st_push(x / y);
    display();
}
 
static void onPush(const char* line) {
    double x = atof(line);
    st_push(x);
}
 
static void onSin() {
    double x;
    if (st_empty()) {
        printf("Stack empty.");
        return;
    }
    x = st_pop();
    st_push(sin(x));
    display();
}
 
static void onCos() {
    double x;
    if (st_empty()) {
        printf("Stack empty.");
        return;
    }
    x = st_pop();
    st_push(cos(x));
    display();
}
 
static void onExp() {
    double x;
    if (st_empty()) {
        printf("Stack empty.");
        return;
    }
    x = st_pop();
    st_push(exp(x));
    display();
}
 
static void onLog() {
    double x;
    if (st_empty()) {
        printf("Stack empty.");
        return;
    }
    x = st_pop();
    st_push(log(x));
    display();
}
 
static void onSqrt() {
    double x;
    if (st_empty()) {
        printf("Stack empty.");
        return;
    }
    if (st_top() < 0.0) {
        printf("Arg. of square root is negative.");
        return;
    }
    x = st_pop();
    st_push(sqrt(x));
    display();
}
 
static void onPop() {
    st_pop();
}
 
static void onClear() {
    st_clear();
}
 
static void display() {
    if (!st_empty()) {
        printf("=%lf", st_top());
    } else {
        printf("stack empty");
    }
}
 
static void onShow() {
    int d = st_size();
    printf("Depth of stack = %d.", d);
    if (d > 0)
        printf(" Stack elements:");
    else
        printf("");
 
    for (int i = 0; i < d; i++) {
        printf("  %lf", st_elementAt(i));
    }
}
 
static void printHelp() {
    printf(
        "Stack Calculator commands:"
        "    <number>    Push а number in stack"
        "    +, -, *, /  Ariphmetic operations"
        "    sin, cos,   Calculate a function"
        "    exp, log,   "
        "    sqrt        "
        "    =           Display the stack top"
        "    pop         Remove the stack top"
        "    show        Show the stack"
        "    clear       Clear the stack"
        "    quit        Terminate the program"
    );
    
}
 

5

Re: Калькулятор

LeoDevel написав:

Форумчани прошу вашої допомоги..Як я вже писав передімною стояло завдання розробка програми у вигляді калькулятора інтерпритатор арефметичних вмразів заданого формату. В чому полягає моя проблема в мене  16 лютого весілля що потрибує реальної підготовки, а 4 лютого захист курсового по цій темі. Дійсно нема часу розбиратися функції, стеками. і т.п. В мене є алгоритм ну я неможу його завершети...Будь=ласка....
Алгоритм...

#include "stdafx.h"
#include "streal.h" // Інтерфейс"стек"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
 
 
//Прототип функції, реалізуючий команди калькулятора:
// Арефметичні операції
static void onAdd();
static void onSub();
static void onMul();
static void onDiv();
 
// Добавити число в стек(вх: текстовий запис числа)
static void onPush(const char* line);
 
// Обчислення матиматичних функцій
static void onSin();     // sin
static void onCos();     // cos
static void onExp();     // Экспонента
static void onLog();     // Натуральный логарифм
static void onSqrt();    // Квадратний корень
 
// Другие команды
static void onPop();     // Видалити вершину стеку
static void onClear();   // Очистити стек
static void display();   //Надрукуваим вершину стека
static void onShow();    // Надрукуваим содержимое стека
static void printHelp(); //Надрукуваим подсказку
 
int _tmain(int argc, _TCHAR* argv[])
{
    char line[256]; // Буфер для введення  строки
    int linelen;    // Довжина строки
 
    st_init(1024);  // Стек.почати роботу(1024)
                    //   1024 — макс. глубина стека
    printHelp();    // Надрукуваим підсказку
 
    while (true) {          // Цикл до нескінченості
        scanf("%s", line);      // ввести строку
        linelen = strlen(line); // довжина строки
        if (linelen == 0)
            continue;
 
   
        if (strcmp(line, "+") == 0) {
            onAdd();
        } else if (strcmp(line, "-") == 0) {
            onSub();
        } else if (strcmp(line, "*") == 0) {
            onMul();
        } else if (strcmp(line, "/") == 0) {
            onDiv();
        } else if (strcmp(line, "sin") == 0) {
            onSin();
        } else if (strcmp(line, "cos") == 0) {
            onCos();
        } else if (strcmp(line, "exp") == 0) {
            onExp();
        } else if (strcmp(line, "log") == 0) {
            onLog();
        } else if (strcmp(line, "sqrt") == 0) {
            onSqrt();
        } else if (strcmp(line, "=") == 0) {
            display();
        } else if (         // Если это число
            isdigit(line[0]) || (
                linelen > 1 &&
                (line[0] == '-' || line[0] == '+') && isdigit(line[1])
            )
        ) {
            onPush(line);   // Добавить число в стек
        } else if (strcmp(line, "pop") == 0) {
            onPop();
        } else if (strcmp(line, "clear") == 0) {
            onClear();
        } else if (strcmp(line, "show") == 0) {
            onShow();
        } else if (strcmp(line, "quit") == 0) {
            break;       // Закінчити работу
        } else {         // Неправильна команда =>
            printHelp(); //    Надрукувати підсказку
        }
    }
    return 0;
}
 
static void onAdd() {
    double y, x;
    if (st_size() < 2) {
        printf("Stack depth < 2.");
        return;
    }
    y = st_pop();
    x = st_pop();
    st_push(x + y);
    display();
}
 
static void onSub() {
    double y, x;
    if (st_size() < 2) {
        printf("Stack depth < 2.");
        return;
    }
    y = st_pop();
    x = st_pop();
    st_push(x - y);
    display();
}
 
static void onMul() {
    double y, x;
    if (st_size() < 2) {
        printf("Stack depth < 2.");
        return;
    }
    y = st_pop();
    x = st_pop();
    st_push(x * y);
    display();
}
 
static void onDiv() {
    double y, x;
    if (st_size() < 2) {
        printf("Stack depth < 2.");
        return;
    }
    y = st_pop();
    x = st_pop();
    st_push(x / y);
    display();
}
 
static void onPush(const char* line) {
    double x = atof(line);
    st_push(x);
}
 
static void onSin() {
    double x;
    if (st_empty()) {
        printf("Stack empty.");
        return;
    }
    x = st_pop();
    st_push(sin(x));
    display();
}
 
static void onCos() {
    double x;
    if (st_empty()) {
        printf("Stack empty.");
        return;
    }
    x = st_pop();
    st_push(cos(x));
    display();
}
 
static void onExp() {
    double x;
    if (st_empty()) {
        printf("Stack empty.");
        return;
    }
    x = st_pop();
    st_push(exp(x));
    display();
}
 
static void onLog() {
    double x;
    if (st_empty()) {
        printf("Stack empty.");
        return;
    }
    x = st_pop();
    st_push(log(x));
    display();
}
 
static void onSqrt() {
    double x;
    if (st_empty()) {
        printf("Stack empty.");
        return;
    }
    if (st_top() < 0.0) {
        printf("Arg. of square root is negative.");
        return;
    }
    x = st_pop();
    st_push(sqrt(x));
    display();
}
 
static void onPop() {
    st_pop();
}
 
static void onClear() {
    st_clear();
}
 
static void display() {
    if (!st_empty()) {
        printf("=%lf", st_top());
    } else {
        printf("stack empty");
    }
}
 
static void onShow() {
    int d = st_size();
    printf("Depth of stack = %d.", d);
    if (d > 0)
        printf(" Stack elements:");
    else
        printf("");
 
    for (int i = 0; i < d; i++) {
        printf("  %lf", st_elementAt(i));
    }
}
 
static void printHelp() {
    printf(
        "Stack Calculator commands:"
        "    <number>    Push а number in stack"
        "    +, -, *, /  Ariphmetic operations"
        "    sin, cos,   Calculate a function"
        "    exp, log,   "
        "    sqrt        "
        "    =           Display the stack top"
        "    pop         Remove the stack top"
        "    show        Show the stack"
        "    clear       Clear the stack"
        "    quit        Terminate the program"
    );
    
}
 

Вибиває помилку звязаної з бібліотекою #include "streal.h" // Інтерфейс"стек"

6

Re: Калькулятор

Помилка очевидна: такий файл не лежить у папці з файлом коду, який ви наводите.

7

Re: Калькулятор

Bartash написав:

Помилка очевидна: такий файл не лежить у папці з файлом коду, який ви наводите.

Можна конкретніше...

8

Re: Калькулятор

Ви написали у коді

#include "streal.h"

.

Це означає для компілятора, що під час збирання проекту та компіляції коду необхідно підключити файл з іменем streal.h, який знаходиться у тій же директорії, що і файл з кодом, де streal.h підключаєте.

Наскільки розумію, цей файл не є стандартним, а створений вами.

9

Re: Калькулятор

Bartash написав:

Ви написали у коді

#include "streal.h"

.

Це означає для компілятора, що під час збирання проекту та компіляції коду необхідно підключити файл з іменем streal.h, який знаходиться у тій же директорії, що і файл з кодом, де streal.h підключаєте.

Наскільки розумію, цей файл не є стандартним, а створений вами.

Все правильно ви сказали, тепер з тим немає проблем. Виникли проблеми з ідентифікаторами...

10

Re: Калькулятор

LeoDevel написав:

Виникли проблеми з ідентифікаторами...

Тобто?
Якщо маєте помилки компіляції - запостіть текст помилки, виданої компілятором. Якщо щось інше - поясніть.

11

Re: Калькулятор

Bartash написав:
LeoDevel написав:

Виникли проблеми з ідентифікаторами...

Тобто?
Якщо маєте помилки компіляції - запостіть текст помилки, виданої компілятором. Якщо щось інше - поясніть.

Ошибка    1    error C2601: sum: недопустимые локальные определения функций

12

Re: Калькулятор

LeoDevel написав:

Ошибка    1    error C2601: sum: недопустимые локальные определения функций

Синім полум'ям горіла б русифікована студія...
Компілятор чимось незадоволений щодо функції sum().

З.І: Скиньте мені сам проект - може, швидше співпраця піде. :)