Отладка постфиксного калькулятора - PullRequest
1 голос
/ 27 марта 2012

Моя задача - построить постфиксный калькулятор, используя связанный список для представления стека. Я написал следующий код для калькулятора, однако получаю ошибку компилятора, которую я не понимаю. Ошибка происходит из файла postfixcalc.cpp и происходит в операторе if в operand2 = opers.getTop (op). Ошибка гласит: «значение не игнорируется, как должно быть». Я использую Dev-C ++ и никогда не сталкивался с сообщениями такого типа. Любое понимание будет оценено. Также, при необходимости, я могу предоставить файлы StackP.

/** @file postfixcalc.h*/
#include "StackP.cpp"
#include <string>

using namespace std;
const int MAX_CHARS = 100;

class postfixcalc
{
public:
/** Default constructor. */
    postfixcalc();

// postfixcalc operations:
    void read();
    void show();
    int eval();

private:
    string e;
    Stack opers;
    char stringInput[MAX_CHARS];
    char *p;
};


/** @file postfixcalc.cpp*/

#include <iostream>
#include <cstring>
#include "postfixcalc.h"

using namespace std;

postfixcalc::postfixcalc()
{}

void postfixcalc::read()
{
    cout << "Please enter a postfix expression: ";
    getline(cin, e);

}//end read

void postfixcalc::show()
{
    cout << e << endl;
}//end show

int postfixcalc::eval()
{
    int operand1, operand2, result;
    int op;

    p = strtok(stringInput, " ");
    while(p)
    {
    op = p[0];
    if( op == '+' || op == '-' || op == '*' || op == '/')
    {
        operand2 = opers.getTop(op);
        opers.pop();
        operand1 = opers.getTop(op);
        opers.pop();

        switch(op)
        {
            case '+':
                    result = operand1 + operand2;
                    break;
            case '-':
                    result = operand1 - operand2;
                    break;
            case '*':
                    result = operand1 * operand2;
                    break;
            case '/':
                    result = operand1 / operand2;
                    break;
        }//end switch
        opers.push(result);
    }
    else
    {
        opers.push(op);
    }
    p = strtok(NULL, " ");
}//end while
}//end eval

Вот реализация StackP

/** @file StackP.h */

#include "StackException.h"
typedef int StackItemType;

/** ADT stack - Pointer-based implementation. */
class Stack
{
public:
// Constructors and destructor:

   /** Default constructor. */
   Stack();

   /** Copy constructor.
    * @param aStack The stack to copy. */
   Stack(const Stack& aStack);

   /** Destructor. */
   ~Stack();

// Stack operations:
   bool isEmpty() const;
   void push(const StackItemType& newItem) throw(StackException);
   void pop() throw(StackException);
   void pop(StackItemType& stackTop) throw(StackException);
   void getTop(StackItemType& stackTop) const
      throw(StackException);

private:
   /** A node on the stack. */
   struct StackNode
   {
      /** A data item on the stack. */
      StackItemType item;
      /** Pointer to next node.     */
      StackNode    *next;
   }; // end StackNode

   /** Pointer to first node in the stack. */
   StackNode *topPtr;
}; // end Stack

/** @file StackP.cpp */

#include <cstddef>   // for NULL
#include <new>       // for bad_alloc
#include "StackP.h"  // header file

using namespace std;

Stack::Stack() : topPtr(NULL)
{
}  // end default constructor

Stack::Stack(const Stack& aStack)
{
   if (aStack.topPtr == NULL)
      topPtr = NULL;  // original list is empty

   else
   {  // copy first node
      topPtr = new StackNode;
      topPtr->item = aStack.topPtr->item;

      // copy rest of list
      StackNode *newPtr = topPtr;    // new list pointer
      for (StackNode *origPtr = aStack.topPtr->next;
       origPtr != NULL; origPtr = origPtr->next)
      {  newPtr->next = new StackNode;
         newPtr = newPtr->next;
     newPtr->item = origPtr->item;
      }  // end for

      newPtr->next = NULL;
   }  // end if
}  // end copy constructor

Stack::~Stack()
{
   // pop until stack is empty
   while (!isEmpty())
      pop();
   // Assertion: topPtr == NULL
}  // end destructor

bool Stack::isEmpty() const
{
   return topPtr == NULL;
}  // end isEmpty

void Stack::push(const StackItemType& newItem)
        throw(StackException)
{
   // create a new node
   try
   {
      StackNode *newPtr = new StackNode;

      // set data portion  of new node
      newPtr->item = newItem;

      // insert the new node
      newPtr->next = topPtr;
      topPtr = newPtr;
   }
   catch (bad_alloc e)
   {
      throw StackException(
     "StackException: push cannot allocate memory.");
   }  // try
}  // end push

void Stack::pop() throw(StackException)
{
   if (isEmpty())
      throw StackException("StackException: stack empty on pop");
   else
   {  // stack is not empty; delete top
      StackNode *temp = topPtr;
      topPtr = topPtr->next;
      // return deleted node to system
      temp->next = NULL;  // safeguard
      delete temp;
   }  // end if
}  // end pop

void Stack::pop(StackItemType& stackTop) throw(StackException)
{
   if (isEmpty())
     throw StackException("StackException: stack empty on pop");
   else
   {  // stack is not empty; retrieve and delete top
      stackTop = topPtr->item;
      StackNode *temp = topPtr;
      topPtr = topPtr->next;

      // return deleted node to system
      temp->next = NULL;  // safeguard
      delete temp;
   }  // end if
}  // end pop

void Stack::getTop(StackItemType& stackTop) const throw(StackException)
{
   if (isEmpty())
      throw StackException("StackException: stack empty on getTop");
   else
      // stack is not empty; retrieve top
      stackTop = topPtr->item;
}  // end getTop

Это ошибка компилятора:

C: \ Documents and Settings \ Владелец \ Мой ... В функции-член `int postfixcalc :: eval () ':

35 C: \ Documents and Settings \ Владелец ... void значение не игнорируется, как и должно быть

37 C: \ Documents and Settings \ Владелец ... void значение не игнорируется, как и должно быть

Ответы [ 2 ]

1 голос
/ 27 марта 2012
void Stack::getTop(StackItemType& stackTop) const throw(StackException)

int postfixcalc::eval()
{
int operand1, operand2, result;
    operand2 = opers.getTop(op);

Функция getTop ничего не возвращает, а затем вы берете это ничего и сохраняете в int. Я думаю, что вы хотели что-то подобное для этой строки:

   opers.getTop(operand2); 
1 голос
/ 27 марта 2012

Stack::getTop() объявлено так:

void getTop(StackItemType& stackTop);

void означает, что функция не возвращает значение. Таким образом, попытка присвоить результат вызова opers.getTop() для operand2 невозможна, потому что getTop() ничего не возвращает! getTop() принимает параметр reference , поэтому он может присвоить верхнее значение непосредственно передаваемой переменной:

opers.getTop(operand2);

Вместо написания своего собственного Stack класса, вы можете просто использовать std::stack:

#include <stack>
#include <iostream>

int main(int argc, char** argv) {
    std::stack<int> stack;
    stack.push(3);
    std::cout << stack.top() << '\n';
    stack.pop();
}

… Если, конечно, это не учебное упражнение, в этом случае просто оставьте отзыв на будущее. Как только вы узнаете, как что-то делается, вы должны воспользоваться тем фактом, что другие люди уже сделали эту работу за вас многократно.

...