Мой калькулятор не работает, когда первый операнд равен нулю
Я новичок в C#. Решил попробовать Windows Forms (до этого работал только с консолью). По официальной документации сделал макет приложения, логику же решил написать сам, пытаясь повторить поведение стандартного калькулятора Windows.
Работает всё следующим образом:
_operation
хранит значение (enum Operation
) последней используемой операции;_operatorActive
принимаетtrue
если есть незавершённая операция (например: пользователь нажал '+', но ещё не нажал '=');_inputActive
: если значениеfalse
, то при вводе числа панель вывода (textBox1
) сначала очищается (чтобы ввести новое число);- Если пользователь, после выбора операции не введёт второй операнд (
_secondOperand
), а сразу нажмет '=', то второй операнд будет равен первому (_firstOperand
); - Если пользователь, после выбора операции и ввода второго операнда, выберет ещё одну операцию (вместо '='), то предыдущая операция выполнится автоматически, а её результат станет первым операндом для текущей операции;
- Если пользователь будет несколько раз подряд нажимать на '=', то будет выполняться последняя сохранённая операция с последним сохранённым вторым операндом.
Всё работает как задумано, НО если первый операнд равен нулю (_firstOperand = 0
), то при выборе операции сложения, результат операции не присваивается первому операнду. Однако если первый операнд равен любому другому числу – всё работает корректно.
С операцией вычитания и умножения всё также работает корректно (деление пока не реализовано).
Также всё работает правильно и в следующем случае:
- Мы сначала выполняем какую-либо операцию с другим значением первого операнда (например: 3 + 5, и нажимаем '=');
- После – устанавливаем первому операнду значение 0 (просто нажимаем на '0');
- Повторно нажимаем '=';
- В этом случае, как и ожидалось, выполнится предыдущая операция, но с другим первым операндом;
Код:
namespace Calculator;
public partial class Form1 : Form
{
private int _result, _firstOperand, _secondOperand;
private Operation? _operation = null;
private bool _operatorActive = false;
private bool _inputActive = false;
public Form1()
{
InitializeComponent();
textBox1.Text = _result.ToString();
UpdateDebugValues();
}
private void NumButton_Click(object sender, EventArgs e)
{
if (textBox1.MaxLength > textBox1.Text.Length)
{
if (!_inputActive)
{
textBox1.Clear();
_inputActive = true;
}
textBox1.Text += (sender as Button)!.Text;
}
UpdateDebugValues();
}
private void ClearButton_Click(object sender, EventArgs e)
{
_operatorActive = false;
_inputActive = false;
_result = 0;
_operation = null;
_secondOperand = 0;
textBox1.Clear();
textBox1.Text = _result.ToString();
UpdateDebugValues();
}
private void OperButton_Click(object sender, EventArgs e)
{
if (_operatorActive)
{
EqualsButton_Click(sender, e);
}
_operatorActive = true;
_operation = (Operation?)(sender as Button)!.Tag;
_secondOperand = _firstOperand;
_inputActive = false;
UpdateDebugValues();
}
private void EqualsButton_Click(object sender, EventArgs e)
{
if (_operation == null)
{
_result = _firstOperand;
}
else
{
_result = Expression.Calculate(_firstOperand, _secondOperand, _operation);
}
_operatorActive = false;
textBox1.Text = _result.ToString();
_inputActive = false;
UpdateDebugValues();
}
private void TextBox1_TextChanged(object sender, EventArgs e)
{
if (int.TryParse(textBox1.Text, out int value))
{
if (_operatorActive)
{
_secondOperand = value;
}
else
{
_firstOperand = value;
}
}
}
private void UpdateDebugValues()
{
firstText.Text = _firstOperand.ToString();
operText.Text = _operation?.ToString() ?? "NULL";
operActText.Text = _operatorActive.ToString();
secondText.Text = _secondOperand.ToString();
resultText.Text = _result.ToString();
}
}
Дополнительно:
- Под вводом числа и выбором операции подразумевается нажатие соответствующих кнопок;
UpdateDebugValues()
отображает значения переменных в окне приложения. На логику программы не влияет;Expression.Calculate(int, int, Operation?)
возвращает результат операции:
internal static class Expression
{
public static int Calculate(int leftOperand, int rightOperand, Operation? operationType)
{
return operationType switch
{
Operation.Add => leftOperand + rightOperand,
Operation.Subtract => leftOperand - rightOperand,
Operation.Multiply => leftOperand * rightOperand,
Operation.Divide => leftOperand / rightOperand,
_ => throw new ArgumentException("Unknown operation."),
};
}
}
- GitHub-репозиторий проекта: https://github.com/X1a0m1/WinFormsCalculator
P.S. Это мой первый вопрос на StackOverflow. Обычно все ответы на мои вопросы уже где-нибудь подробно расписаны, но этот я даже не придумал как кратко описать :)