Могу ли я использовать переключатель для удержания функции? - PullRequest
0 голосов
/ 03 июня 2010

У меня есть 3-х файловая программа, в основном я учу себя с ++.У меня есть проблема.Я сделал переключатель, чтобы использовать математическую функцию.Мне нужно и положить его в переменную, но по какой-то причине я получаю ноль в результате.

Еще одна проблема, когда я выбираю 4 (делить), он падает ... Есть причина?

Основной файл:

#include <iostream>
#include "math.h"
#include <string>

using namespace std;

int opersel;
int c;
int a;
int b;
string test;

int main(){

cout << "Welcome to Math-matrix v.34"<< endl;
cout << "Shall we begin?" <<endl;

//ASK USER IF THEY ARE READY TO BEGIN 

string answer;
cin >> answer;

if(answer == "yes" || answer == "YES" || answer == "Yes")
{

           cout << "excellent lets begin..." << endl;

           cout << "please select a operator..." << endl  << endl;


           cout << "(1) + " << endl;
           cout << "(2) - " << endl;
           cout << "(3) * " << endl;
           cout << "(4) / " << endl;

           cin >> opersel;

           switch(opersel){

                  case 1:
                  c = add(a,b);
                  break;
                  case 2:
                  c = sub(a,b);
                  break;
                  case 3:
                  c = multi(a,b);
                  break;
                  case 4:
                  c = divide(a,b);
                  break;
                  default:
                  cout << "error... retry" << endl;

                  }// end retry


           cout << "alright, how please select first digit?" << endl;

           cin >> a;

           cout << "excellent... and your second?" << endl;

           cin >> b;

           cout << c;

           cin >> test;

           }else if (answer == "no" || answer == "NO" || answer == "No"){


                 }//GAME ENDS








}// end of int main 

Вот мой math.h file

#ifndef MATH_H
#define MATH_H

int add(int a, int b);


int sub(int a, int b);



int multi(int a, int b);


int divide(int a, int b);

#endif

Вот мой math.cpp:

int add(int a, int b)
{

 return a + b;   

}

int sub(int a, int b)
{

 return a - b;   

}

int multi(int a, int b)
{

 return a * b;   

}

int divide(int a, int b)
{

 return a / b;   

}






}// end of int main 

Ответы [ 8 ]

5 голосов
/ 03 июня 2010

Вы вызываете свои функции с помощью a и b до того, как получите данные от пользователя. Попробуйте сохранить математическую функцию, выбранную ими при входе в нее, и переместите переключатель в положение после того, как вы запросили их a и b.

#include <iostream>
#include "math.h"
#include <string>

using namespace std;

int opersel;
int c;
int a;
int b;
string test;

int main(){

cout << "Welcome to Math-matrix v.34"<< endl;
cout << "Shall we begin?" <<endl;

//ASK USER IF THEY ARE READY TO BEGIN 

string answer;
cin >> answer;

if(answer == "yes" || answer == "YES" || answer == "Yes")
{

           cout << "excellent lets begin..." << endl;

           cout << "please select a operator..." << endl  << endl;


           cout << "(1) + " << endl;
           cout << "(2) - " << endl;
           cout << "(3) * " << endl;
           cout << "(4) / " << endl;

           cin >> opersel;              

           cout << "alright, how please select first digit?" << endl;

           cin >> a;

           cout << "excellent... and your second?" << endl;

           cin >> b;

           switch(opersel){

                  case 1:
                  c = add(a,b);
                  break;
                  case 2:
                  c = sub(a,b);
                  break;
                  case 3:
                  c = multi(a,b);
                  break;
                  case 4:
                  c = divide(a,b);
                  break;
                  default:
                  cout << "error... retry" << endl;

           }// end retry

           cout << c;

           cin >> test;

           }else if (answer == "no" || answer == "NO" || answer == "No"){       
                 }//GAME ENDS   
}// end of int main 
0 голосов
/ 03 июня 2010

Вот идея (используя функциональные объекты или функторы ):

#include <iostream>
using std::cin;
using std::cout;
struct Math_Operation
{
  virtual int operator()(int a, int b) = 0;
};

struct Math_Add : Math_Operation
{
  int operator()(int a, int b)
  { return a + b;}
};

struct Math_Sub : Math_Operation
{
  int operator()(int a, int b)
  { return a - b;}
};

struct Math_Mul : Math_Operation
{
  int operator()(int a, int b)
  { return a * b;}
};

struct Math_Div : Math_Operation
{
  int operator()(int a, int b)
  { return a / b;}
};


int main(void)
{
  cout << "Enter operation (+, -, *, /): ";
  cout.flush();
  char operation;
  Math_Operation * p_math_opr = NULL;
  cin >> operation;
  switch (operation)
  {
    case '+':
      p_math_opr = new Math_Add;
      break;
    case '-':
      p_math_opr = new Math_Sub;
      break;
    case '*':
      p_math_opr = new Math_Mul;
      break;
    case '/':
      p_math_opr = new Math_Div;
      break;
    default:
      p_math_opr = NULL;
  }

// ...Input numbers into A & B...
  int A = 5;
  int B = 8;

//  Perform calculation with A & B
  int Result = 0;
  if (p_math_opr)
  {
      Result = (*p_math_opr)(A, B);
      delete p_math_opr;
  }
  cout << "Result is: " << Result << "\n";
  return 0;
}

Функторный подход позволяет сохранить операцию. Использование указателей на базовый класс позволяет вам выполнять функтор, не зная, какая операция «используется».

Edit:
1. Добавлен int в определения функций в дочерних классах.
2. Исправлен синтаксис выполнения функтора.
3. Добавлено удаление функтора.

0 голосов
/ 03 июня 2010

c = add(a,b); в вашем выражении switch не сохраняет функцию, она вызывает функцию, передавая ей a и b в качестве аргументов. Это то же самое для всех остальных ваших случаев. Но на тот момент в программе вы еще не установили a и b. Они неинициализированы, поэтому они могут быть чем угодно. Включая 0, что может вызвать проблемы при разделении. Редактировать: На самом деле, я только что понял, что они глобальные. Поэтому они должны быть инициализированы для вас нулем, что гарантировало бы, что опция деления не удастся. Если бы a и b были локальными с точностью до main, они были бы неинициализированы, и вы не могли бы сделать никаких предположений относительно того, что они изначально содержат.

Можно сохранить адрес для указателя, но это довольно сложная тема, и я бы порекомендовал вам подождать, пока вы не разберетесь с основами, прежде чем углубляться в него. Пока что вам лучше всего получать все ваши данные от пользователя, а затем обрабатывать все сразу. В псевдокоде ваш цикл будет выглядеть примерно так:

Get Operator
If Operator < 0 or Operator > 4 Then "Error"
Get A
Get B
Switch Operator
    1: Result = Add(A, B)
    2: Result = Subtract(A, B)
    3: Result = Multiply(A, B)
    4: Result = Divide(A, B)
Output result

Обратите внимание, что существует много"ошибок", когда дело доходит до ввода пользователя. Например, когда вы просите пользователя ввести значение для a, что если он введет «Пять»? По крайней мере, вы захотите проверить статус cin после любого ввода; это скажет вам, получил ли он какие-либо действительные данные от пользователя или нет. cin.good() должен сообщить вам, была ли предыдущая операция успешной, и если нет, вы можете выйти, или попытаться снова, или как вам угодно.

0 голосов
/ 03 июня 2010

Это вызов функции:

c = add(a,b);

Он присваивает c возвращаемое значение вызова add с параметрами a и b. В то время, когда вы вызываете эту функцию, a и b не были инициализированы. Поставьте свой переключатель после этой строки:

cin >> b;

и все должно работать так, как вы ожидаете.

0 голосов
/ 03 июня 2010

Вы выполняете свои вычисления еще до того, как прочитали a и b в их переменных. Операторы cin >> следуют после ваших операторов switch.

0 голосов
/ 03 июня 2010

Вы вызываете математические функции в своем операторе switch до того, как прочитали a и b от пользователя, поэтому он вызывается с тем, что происходит в этих переменных в данный момент. Вам нужно переместить переключатель после чтения a и b от пользователя, перед выводом c

Это может быть слишком сложным, но вместо использования переключателя вы можете использовать массив указателей на функции:

typedef int (*math_function)(int, int);
math_function fns[] = {NULL, add, sub, multi, divide};

cin >> opersel;
if(opersel <= 4)
    cout << fns[opersel](a, b);
else
    cout << "You fail :(";
0 голосов
/ 03 июня 2010

Похоже, что вы вызываете свои математические функции (внутри оператора switch), прежде чем заполнить свои входные переменные a и b. Переместите вызовы cin выше переключателя, и ваши проблемы должны исчезнуть.

Сбой, скорее всего, вызван, когда вы вызываете деление (a, b), потому что a и b оба равны 0. В этом случае вы делитесь на ноль, и система не будет рада этому.

0 голосов
/ 03 июня 2010

Вам нужно переместить эти:

   cout << "alright, how please select first digit?" << endl;
   cin >> a;
   cout << "excellent... and your second?" << endl;
   cin >> b;

до переключения. Если вы думаете, что такая функция:

int f( int x, int y ) {
   return x + y;
}

каким-то образом возвращает выражение «x + y», которое может быть вычислено позже, но не может. Возвращает результат оценки x + y в этой точке программы. Существуют языки, которые могут возвращать выражения, но C ++ не является одним из них.

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