Как создать калькулятор c#
В данном уроке мы разработаем с вами калькулятор на C#. Программа будет написана согласно принципам объектно-ориентированного программирования (ООП): будет определен интерфейс для методов, реализующих функционал клавиш математических операций калькулятора, от интерфейса выполним наследование и напишем соответствующий класс и методы. Калькулятор, помимо базовых операций сложения, вычитания, умножения и деления, будет предоставлять возможность выполнять операции: извлечения квадратного корня, извлечения корня произвольной степени, возведения в квадрат, возведения в произвольную степень, вычисления факториала, а также работу с регистром памяти (MRC).
Создание интерфейса.
Создадим в Visual Studio проект на Visual C# Windows Forms. Добавим на форму элемент GroupBox, в который поместим Label. В свойстве Dock, элемента Label, необходимо указать Right, чтобы Label был привязан к правому краю. Связка данных элементов управления будет реализовывать дисплей калькулятора.
Калькулятор также содержит кнопки. Всего их 28 штук.
Программирование калькулятора на C#Реализация интерфейса класса.
Поскольку наш калькулятор будет написан в рамках парадигмы ООП (объектно-ориентированного программирования), то начнем кодирование с описания структуры интерфейса для класса, реализующего математические операции программы.
Добавим в проект класс InterfaceCalc.cs и определим в созданном файле интерфейс InterfaceCalc.
//интерфейс
public interface InterfaceCalc
{
//а - первый аргумент, b - второй
void Put_A(double a); //сохранить а
void Clear_A();
double Multiplication(double b);
double Division(double b);
double Sum(double b);
double Subtraction(double b); //вычитание
double SqrtX(double b);
double DegreeY(double b);
double Sqrt();
double Square();
double Factorial();
double MemoryShow(); //показать содержимое регистра памяти
void Memory_Clear(); //стереть содержимое регистра памяти
//* / + - к регистру памяти
void M_Multiplication(double b);
void M_Division(double b);
void M_Sum(double b);
void M_Subtraction(double b); //вычитание
}
Для выполнения математических операций понадобится два операнда: a и b (например, a + b). Операнд a придется хранить в памяти калькулятора, пока пользователь будет вводить второй аргумент операции. Для сохранения числа a объявим прототип метода void Put_A(double a), для очистки — void Clear_A(). Для умножения, деления, сложения и вычитания чисел a и b соответственно понадобятся методы: double Multiplication(double b), double Division(double b), double Sum(double b), double Subtraction(double b). Вычисление корня степени b из a: double SqrtX(double b). Возведение числа a в степень b: double DegreeY(double b). Вычисление квадратного корня: double Sqrt(). Возведение числа a в квадрат: double Square(). Вычисление факториала a!: double Factorial(). Теперь объявления методов для работы с регистром памяти (MRC) калькулятора. Показать содержимое памяти и очистить его: double MemoryShow(), void Memory_Clear(). M×, M÷, M+ и M- к регистру соответственно: void M_Multiplication(double b), void M_Division(double b), void M_Sum(double b), void M_Subtraction(double b).
Создание класса, реализующего интерфейс InterfaceCalc
Теперь добавим в калькулятор класс, который будет реализовывать написанный ранее интерфейс. Для этого в проекте создадим класс Calc : InterfaceCalc. Как вы видите, здесь используется наследование (оператор «двоеточие»). В данном классе напишем реализацию всех методов, требуемых спецификацией нашего интерфейса.
public class Calc : InterfaceCalc
{
private double a = 0;
private double memory = 0;
public void Put_A(double a)
{
this.a = a;
}
public void Clear_A()
{
a = 0;
}
public double Multiplication(double b)
{
return a * b;
}
public double Division(double b)
{
return a / b;
}
public double Sum(double b)
{
return a + b;
}
public double Subtraction(double b) //вычитание
{
return a - b;
}
public double SqrtX(double b)
{
return Math.Pow(a, 1 / b);
}
public double DegreeY(double b)
{
return Math.Pow(a, b);
}
public double Sqrt()
{
return Math.Sqrt(a);
}
public double Square()
{
return Math.Pow(a, 2.0);
}
public double Factorial()
{
double f = 1;
for (int i = 1; i <= a; i++)
f *= (double)i;
return f;
}
//показать содержимое регистра мамяти
public double MemoryShow()
{
return memory;
}
//стереть содержимое регистра мамяти
public void Memory_Clear()
{
memory = 0.0;
}
//* / + - к регистру памяти
public void M_Multiplication(double b)
{
memory *= b;
}
public void M_Division(double b)
{
memory /= b;
}
public void M_Sum(double b)
{
memory += b;
}
public void M_Subtraction(double b)
{
memory -= b;
}
}
Реализация работы калькулятора
Перейдем к написанию кода в классе Form1.
Объявим два поля:
CalcC;
int k;
Это классовая переменная C для класса Calc и целое число k. С помощью k будем считать количество нажатий кнопки MRC, чтобы при первом нажатии выводить значение регистра памяти на экран, а при последующем повторном — стирать значение регистра.
Далее. Нам понадобится ряд методов, которые будут обеспечивать правильное функционирование калькулятора.
Дисплеем в нашем калькуляторе является Label. Его содержимое — это строка текста. Нажатие на цифровые клавиши — это конкатенация текущего значения строки с символом клавиши. Необходимо исключить дублирование нулей в левой части строки (это делают 2-й и 3-й if в коде ниже), а также не допустить написание цифр, если в Label находится знак «бесконечность» (он появляется, например, при делении на ноль; 1-й if). Для решения данных проблем напишем метод CorrectNumber():
privatevoidCorrectNumber(){//если есть знак "бесконечность" - не даёт писать цифры после негоif(labelNumber.Text.IndexOf("∞")!=-1)labelNumber.Text=labelNumber.Text.Substring(0,labelNumber.Text.Length-1);//ситуация: слева ноль, а после него НЕ запятая, тогда ноль можно удалитьif(labelNumber.Text[0]=='0'&& (labelNumber.Text.IndexOf(",") != 1)) labelNumber.Text = labelNumber.Text.Remove(0, 1);//аналогично предыдущему, только для отрицательного числаif(labelNumber.Text[0]=='-')if(labelNumber.Text[1]=='0'&& (labelNumber.Text.IndexOf(",") != 2)) labelNumber.Text = labelNumber.Text.Remove(1, 1);}
Еще необходим метод, проверяющий: не нажата ли какая-нибудь кнопка калькулятора из математических операций, требующих два операнда. Данная проверка необходима для недопущения нажатия других мат. операций, если какая-либо уже нажата. Код метода CanPress():
privateboolCanPress(){if(!buttonMult.Enabled)returnfalse;if(!buttonDiv.Enabled)returnfalse;if(!buttonPlus.Enabled)returnfalse;if(!buttonMinus.Enabled)returnfalse;if(!buttonSqrtX.Enabled)returnfalse;if(!buttonDegreeY.Enabled)returnfalse;returntrue;}
Также, напишем вспомогательный метод FreeButtons(), который снимает нажатия со всех кнопок математических операций калькулятора, требующих два операнда (умножение, деление, сложение, вычитание, вычисление корня произвольной степени и возведение числа в произвольную степень):
privatevoidFreeButtons(){buttonMult.Enabled=true;buttonDiv.Enabled=true;buttonPlus.Enabled=true;buttonMinus.Enabled=true;buttonSqrtX.Enabled=true;buttonDegreeY.Enabled=true;}
Со вспомогательными методами закончили. Идем дальше.
В конструкторе Form1 создадим экземпляр класса Calc, а также в «дисплей» калькулятора занесем значение ноль.
publicForm1(){InitializeComponent();C=newCalc();labelNumber.Text="0";}
Теперь перейдем к кодированию обработчиков нажатий кнопок калькулятора. Кнопка «Очистка» (CE):
privatevoidbuttonClear_Click(objectsender,EventArgse){labelNumber.Text="0";C.Clear_A();FreeButtons();k=0;}
В «дисплей» записывается ноль, переменная a стирается, нажатия с кнопок математических операций снимаются и k обнуляется.
Кнопка изменения знака у числа «+/-«:
privatevoidbuttonChangeSign_Click(objectsender,EventArgse){if(labelNumber.Text[0]=='-')labelNumber.Text=labelNumber.Text.Remove(0,1);elselabelNumber.Text="-"+labelNumber.Text;}
Кнопка «запятая» (будет добавлена, если ее еще нет и на «дисплее» нет знака бесконечность):
privatevoidbuttonPoint_Click(objectsender,EventArgse){if((labelNumber.Text.IndexOf(",")==-1)&& (labelNumber.Text.IndexOf("∞") == -1)) labelNumber.Text += ",";}
Теперь цифровые клавиши 0, 1, 2, 3, 4, 5, 6, 7, 8, 9:
privatevoidbutton0_Click(objectsender,EventArgse){labelNumber.Text+="0";CorrectNumber();}privatevoidbutton1_Click(objectsender,EventArgse){labelNumber.Text+="1";CorrectNumber();}privatevoidbutton2_Click(objectsender,EventArgse){labelNumber.Text+="2";CorrectNumber();}privatevoidbutton3_Click(objectsender,EventArgse){labelNumber.Text+="3";CorrectNumber();}privatevoidbutton4_Click(objectsender,EventArgse){labelNumber.Text+="4";CorrectNumber();}privatevoidbutton5_Click(objectsender,EventArgse){labelNumber.Text+="5";CorrectNumber();}privatevoidbutton6_Click(objectsender,EventArgse){labelNumber.Text+="6";CorrectNumber();}privatevoidbutton7_Click(objectsender,EventArgse){labelNumber.Text+="7";CorrectNumber();}privatevoidbutton8_Click(objectsender,EventArgse){labelNumber.Text+="8";CorrectNumber();}privatevoidbutton9_Click(objectsender,EventArgse){labelNumber.Text+="9";CorrectNumber();}
Кнопка «Равно»:
private void buttonCalc_Click(object sender, EventArgs e)
{
if (!buttonMult.Enabled)
labelNumber.Text = C.Multiplication(Convert.ToDouble(labelNumber.Text)).ToString();
if (!buttonDiv.Enabled)
labelNumber.Text = C.Division(Convert.ToDouble(labelNumber.Text)).ToString();
if (!buttonPlus.Enabled)
labelNumber.Text = C.Sum(Convert.ToDouble(labelNumber.Text)).ToString();
if (!buttonMinus.Enabled)
labelNumber.Text = C.Subtraction(Convert.ToDouble(labelNumber.Text)).ToString();
if (!buttonSqrtX.Enabled)
labelNumber.Text = C.SqrtX(Convert.ToDouble(labelNumber.Text)).ToString();
if (!buttonDegreeY.Enabled)
labelNumber.Text = C.DegreeY(Convert.ToDouble(labelNumber.Text)).ToString();
C.Clear_A();
FreeButtons();
k = 0;
}
В зависимости от того, какая из кнопок математических операций нажата, будет вызван соответствующий метод из класса Calc, вычисляющий данную функцию, и результат выведется в Label.
Далее кнопки математических операций. Сработают только в том случае, если другие в данный момент не нажаты (CanPress() вернет true):
//кнопка УмножениеprivatevoidbuttonMult_Click(objectsender,EventArgse){if(CanPress()){C.Put_A(Convert.ToDouble(labelNumber.Text));buttonMult.Enabled=false;labelNumber.Text="0";}}//кнопка ДелениеprivatevoidbuttonDiv_Click(objectsender,EventArgse){if(CanPress()){C.Put_A(Convert.ToDouble(labelNumber.Text));buttonDiv.Enabled=false;labelNumber.Text="0";}}//кнопка СложениеprivatevoidbuttonPlus_Click(objectsender,EventArgse){if(CanPress()){C.Put_A(Convert.ToDouble(labelNumber.Text));buttonPlus.Enabled=false;labelNumber.Text="0";}}//кнопка ВычитаниеprivatevoidbuttonMinus_Click(objectsender,EventArgse){if(CanPress()){C.Put_A(Convert.ToDouble(labelNumber.Text));buttonMinus.Enabled=false;labelNumber.Text="0";}}//кнопка Корень произвольной степениprivatevoidbuttonSqrtX_Click(objectsender,EventArgse){if(CanPress()){C.Put_A(Convert.ToDouble(labelNumber.Text));buttonSqrtX.Enabled=false;labelNumber.Text="0";}}//кнопка Возведение в произвольную степеньprivatevoidbuttonDegreeY_Click(objectsender,EventArgse){if(CanPress()){C.Put_A(Convert.ToDouble(labelNumber.Text));buttonDegreeY.Enabled=false;labelNumber.Text="0";}}//кнопка Корень квадратныйprivatevoidbuttonSqrt_Click(objectsender,EventArgse){if(CanPress()){C.Put_A(Convert.ToDouble(labelNumber.Text));labelNumber.Text=C.Sqrt().ToString();C.Clear_A();FreeButtons();}}//кнопка Квадрат числаprivatevoidbuttonSquare_Click(objectsender,EventArgse){if(CanPress()){C.Put_A(Convert.ToDouble(labelNumber.Text));labelNumber.Text=C.Square().ToString();C.Clear_A();FreeButtons();}}//кнопка ФакториалprivatevoidbuttonFactorial_Click(objectsender,EventArgse){if(CanPress()){if((Convert.ToDouble(labelNumber.Text)==(int)(Convert.ToDouble(labelNumber.Text)))&& ((Convert.ToDouble(labelNumber.Text) >= 0.0))) { C.Put_A(Convert.ToDouble(labelNumber.Text));labelNumber.Text=C.Factorial().ToString();C.Clear_A();FreeButtons();}elseMessageBox.Show("Число должно быть >= 0 и целым!");}}
Калькулятор вычислит факториал только в том случае, если текущее введенное число целое и больше, либо равно нулю.
Кнопки математических операций над регистром памяти (MRC):
//кнопка М+privatevoidbuttonMPlus_Click(objectsender,EventArgse){C.M_Sum(Convert.ToDouble(labelNumber.Text));}//кнопка М-privatevoidbuttonMMinus_Click(objectsender,EventArgse){C.M_Subtraction(Convert.ToDouble(labelNumber.Text));}//кнопка М*privatevoidbuttonMMult_Click(objectsender,EventArgse){C.M_Multiplication(Convert.ToDouble(labelNumber.Text));}//кнопка М/privatevoidbuttonMDiv_Click(objectsender,EventArgse){C.M_Division(Convert.ToDouble(labelNumber.Text));}
И последняя кнопка — «MRC». Она показывает содержимое регистра памяти на экран, а при повторном нажатии стирает его:
privatevoidbuttonMRC_Click(objectsender,EventArgse){if(CanPress()){k++;if(k==1)labelNumber.Text=C.MemoryShow().ToString();if(k==2){C.Memory_Clear();labelNumber.Text="0";k=0;}}}
На этом написание калькулятора на C# закончено. Спасибо за прочтение статьи!