Как создать калькулятор c#

В данном уроке мы разработаем с вами калькулятор на C#. Программа будет написана согласно принципам объектно-ориентированного программирования (ООП): будет определен интерфейс для методов, реализующих функционал клавиш математических операций калькулятора, от интерфейса выполним наследование и напишем соответствующий класс и методы. Калькулятор, помимо базовых операций сложения, вычитания, умножения и деления, будет предоставлять возможность выполнять операции: извлечения квадратного корня, извлечения корня произвольной степени, возведения в квадрат, возведения в произвольную степень, вычисления факториала, а также работу с регистром памяти (MRC).

Создание интерфейса.

Создадим в Visual Studio проект на Visual C# Windows Forms. Добавим на форму элемент GroupBox, в который поместим Label. В свойстве Dock, элемента Label, необходимо указать Right, чтобы Label был привязан к правому краю. Связка данных элементов управления будет реализовывать дисплей калькулятора.

Калькулятор также содержит кнопки. Всего их 28 штук.

Как создать калькулятор c#

Программирование калькулятора на 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# закончено. Спасибо за прочтение статьи!

22
Начать дискуссию