2015-05-19 5 views
0

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

An unhandled exception of type 'System.StackOverflowException' occurred in WindowsFormsApplication1.exe

после того, как я нажимаю кнопку +, чтобы написать следующий номер.

public class calculator 
{ 
    int acum = 0; 
    int calcule(int option, int number) 
    { 
     switch (option) 
     { 
      case 3: 
       acum = acum + number; 
       break; 
      case 4: 
       acum = acum - number; 
       break; 
      case 5: 
       acum = acum * number; 
       break; 
      case 6: 
       acum = acum/number; 
       break; 
      default: 
       break; 
     } 
     if (number == 0) 
     { 
      return acum; 
     } 
     else 
     { 
      return calculate(option, number); 
     } 
    } 
} 

private void btnadd_Click(object sender, EventArgs e) 
{ 
    int numero1 = Convert.ToInt32(txtnumber.Text); 

    calculadora calcular = new calculadora(); 

    txtnumber.Text = calculator.calculate(btnadd.TabIndex, number).ToString(); 
} 

private void btnminus_Click(object sender, EventArgs e) 
{ 
    int numero1 = Convert.ToInt32(txtnumber.Text); 

    calculadora calcular = new calculadora(); 

    txtnumber.Text = calculator.calculate(btnminus.TabIndex, number).ToString(); 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    int number = Convert.ToInt32(txtnumber.Text); 

    calculadora calcular = new calculadora(); 

    txtnumber.Text = calculator.calculate(button1.TabIndex, number).ToString(); 
} 

private void button2_Click(object sender, EventArgs e) 
{ 
    int numero1 = Convert.ToInt32(txtnumber.Text); 

    calculadora calcular = new calculadora(); 

    txtnumber.Text = calculator.calculate(button2.TabIndex, number).ToString(); 
} 
+1

Если вы никогда не измените 'option' или' number', а затем вызовите функцию снова, как вы ожидаете выхода из рекурсии? –

+0

Как сказал ранее @RonBeyer, если вход для вычисления не равен 0, вы всегда будете называть вычисление в бесконечной рекурсии, ваше конечное условие недействительно и может также привести к делению на нулевую ошибку – Louis

+3

Что сказал Рон Бейер, t рекурсия с теми же входами. Я заинтригован этой целью. Быстрые предложения, 'calcule' не выглядят так, как будто это должен быть общий код или, по крайней мере, не в текущем состоянии. Выключатели, подобные этим, являются предупреждающими колокольчиками для плохого дизайна. Использование числовых кодов 'case 6' для представления значения также немного подозрительно, вот почему существуют перечисления (я набираю это, и я не могу вспомнить, что такое 6, разделив?: D Да, хорошо угадайте nathan). –

ответ

2

Прежде всего, есть много проблем в вашем коде:

  1. ACUM не статично, каждый раз, когда вы делаете калькулятор известково = новый калькулятор(); значение устанавливается равным нулю. Поэтому, даже если в вашем коде не было ошибок, результатом будет номер.
  2. Значение числа агда никогда не меняется в методе Calculate так что нет никакого способа, вы можете избежать рекурсивного вызова, как только вы входите еще здесь (=> StackOverflowException) if (number == 0) { return acum; } else { return calculate(option, number); }
  3. А также Вычислить (...) является частный ... вы не можете получить доступ к нему вне класса Calculator

Попробуйте это:

 
    enum OperationEnum 
    { 
     ADD=3, 
     SUB=4, 
     MUL=5, 
     DIV=6 
    } 
    public class Calculator 
    { 
     public double Calculate(OperationEnum operation, params int[] operands) 
     { 
      if (operands == null) 
       throw new InvalidOperationException(); 
      if (operands.Length == 0) 
        return 0; 
      if (operands.Length == 1) 
       return operands[0]; 
      switch (operation) 
      { 
       case OperationEnum.ADD: 
        return Add(operands); 
       case OperationEnum.SUB: 
        return Subtract(operands); 
       case OperationEnum.MUL: 
        return Multiply(operands); 
       case OperationEnum.DIV: 
        return Divide(operands); 
       default: 
        throw new ArgumentException("operation"); 
      } 
     } 
     private double Divide(int[] operands) 
     { 
      if (operands.Length == 0) 
       return 0; 
      var result = operands[0]; 
      for (int i = 1; i < operands.Length; i++) 
      { 
       double divider = operands[i]; 
       if (divider == 0) 
       { 
        throw new DivideByZeroException(); 
       } 
       result /= divider; 
      } 
      return result; 
     } 
     private double Multiply(int[] operands) 
     { 
      if (operands.Length == 0) 
       return 0; 
      double result = operands[0]; 
      for (int i = 1; i < operands.Length; i++) 
      { 
       result *= operands[i]; 
      } 
      return result; 
     } 
     private double Subtract(int[] operands) 
     { 
      if (operands.Length == 0) 
       return 0; 
      var result = operands[0]; 
      for (int i = 1; i < operands.Length; i++) 
      { 
       result -= operands[i]; 
      } 
      return result; 
     } 
     private int Add(int[] operands) 
     { 
      return operands.Sum(); 
     } 
    } 
    private double _accumulator = 0; 
    private void btnadd_Click(object sender, EventArgs e) 
    { 
     int numero1 = Convert.ToInt32(txtnumber.Text); 
     Calculator calcular = new Calculator(); 
     _accumulator = calcular.Calculate(OperationEnum.ADD,_accumulator, number); 
     txtnumber.Text = _accumulator.ToString() 
    }

+0

Спасибо. @LeMara, ты дал мне другое представление о том, как делать вещи. Я просто хотел, чтобы мой код работал с рекурсией. –

+0

Да. @LeMara, я бы дал очки, но я не могу, так как у меня недостаточно очков репутации, чтобы сделать это. но спасибо! –

+0

@Mario: Не обращайте внимания на очки. Если мой ответ помог вам, это самое важное. Во всяком случае, вы можете задать вопрос как ответ и принять мой ответ как решение – adPartage

Смежные вопросы