Как сделать калькулятор на C
В этой статье простым языком изложена вся необходимая информация для программирования калькулятора на языке C. Применяемая программа используется на лабораторных занятиях студентов инженерных специальностей первого года обучения. Так что любой студент, например изучающий математическое моделирование в биологии, сможет самостоятельно запрограммировать калькулятор. Попробуем сделать калькулятор и мы.
Цель этой программы
Сделать простой калькулятор на языке программирования C с помощью оператора switch .
Понятия, используемые в программе
Типы данных
Тип данных указывает на вид данных, которые может хранить переменная, например целочисленные типы, числа с плавающей запятой, символьные типы данных и т. д.
В этой программе использованы целочисленные и символьные типы данных — int и char соответственно.
int
Переменная int используется для хранения целых чисел.
Синтаксис для int : int variable_name =integer ; .
Например: int a=10; .
char
Самый распространенный тип данных на C. Он занимает в памяти один байт почти во всех компиляторах.
Синтаксис для char : char variable_name=”single character”; .
Например: char b=”x”; .
Операторы switch
Переключатель (оператор switch ) позволяет проверить переменную на соответствие по списку значений. Каждое значение называется случаем ( case ), и переменная, для которой задействуется оператор switch , проверяется для каждого случая внутри switch .
Синтаксис для switch :
Алгоритм для этой программы
Шаг 1: начало.
Шаг 2: объявляется переменная n, a, b, c типа данных int .
Шаг 3: отображается меню для пользователя.
Шаг 4: читается значение n от пользователя.
Шаг 5: при вводе пользователем любого числа от 1 до 5 выполняется следующий шаг согласно случаю, соответствующему введенному числу.
Шаг 6:
a) случай 1. Читаются значения a и b. Высчитывается сумма a и b. Результат отображается с помощью break; .
б) случай 2. Читаются значения a и b. Высчитывается разность a и b. Результат отображается с помощью break; .
в) случай 3. Читаются значения a и b. Высчитывается произведение a и b. Результат отображается с помощью break; .
г) случай 4. Читаются значения a и b. Высчитывается частное от деления а на b. Результат отображается с помощью break; .
д) случай 5. Читаются значения a и b. Высчитывается квадрат а. Результат отображается с помощью break; .
е) default: отображается Invalid .
Шаг 7: конец.
Блок-схема
Что такое « #include<stdio. h> »?
Заголовочный файл stdio. h расшифровывается как “standard input output” («стандартный ввод/вывод»). В нем содержится информация, связанная с функциями ввода/вывода.
Что такое « #include<conio. h> »?
#include<conio. h> — это заголовочный файл, используемый на C, в котором находятся встроенные функции, такие как getch() и clrscr() . Расшифровывается он как “console input ouput” («ввод/вывод на консоль»), т. е. он принимает ввод с клавиатуры и отображает его на экране.
Что такое « main »?
Функция main() — это точка входа любой программы на Си. Здесь начинается выполнение программы. При этом контроль выполнения переходит непосредственно в функцию main() . Функция main() есть в каждой программе на C.
Что такое « printf » и « scanf »?
Функция printf() задействуется для отображения вывода, а функция scanf() — для принятия пользовательского ввода. Они часто используются в языке C, в частности в заголовочных файлах в качестве встроенных библиотечных функций.
Что такое « switch » и « case »?
Оператор switch позволяет проверить переменную на соответствие по списку значений. Каждое значение называется случаем ( case ), а переменная, для которой задействуется оператор switch , проверяется для каждого случая case внутри switch .
Что такое оператор « break »?
break — это ключевое слово, которое используется в языке C для вывода управления программой из цикла. Оператор break задействуется внутри циклов или внутри оператора switch , прерывая циклы один за другим. То есть в случае вложенных циклов сначала он прерывает внутренний цикл, а затем переходит к внешним.
А для чего на C нужен « default »?
Операторы switch и case используются только для конкретных значений выполняемых операторов case и для проверяемого выражения внутри switch . Когда выражение в switch не соответствует ни одному случаю case , программа выполняет операторы default .
Что такое « ruturn 0 »?
return 0 в функции main означает, что программа выполнена успешно и определяемая пользователем функция возвращает false . return 1 в функции main означает, что программа не выполнена успешно и есть какая-то ошибка, а определяемая пользователем функция возвращает true .
Создаем калькулятор на C# и WinForms
В сегодняшней статье мы создадим простой калькулятор способный выполнять сложение, вычитание, умножение, а также деление. И все это мы реализуем на языке C# и шаблонах Windows Forms. Так что, давайте приступим.
Откройте Visual Studio или Visual C# Express Edition и создайте новый проект.
Установите его тип в приложение Windows Forms и задайте имя в приложения Калькулятор. Нажмите кнопку ОК.
Должно получиться следующее:
Измените свойство текста формы на Калькулятор, потому что мы не хотим, чтобы наше приложение имело заголовок Form1 при запуске. Для чего заходим во вкладку свойтва.
Далее во вкладке Вид находим панель элементов или ToolBox. Поместите элемент управления TextBox на форму и измените его размер. Выполните некоторые изменения в свойствах, как показано на рисунке.
Теперь мы начинаем работать с дисплеем, обычно при запуске калькулятора на нем должно отображаться число 0. В нашем случае это не так. Поэтому мы изменяем свойство Text и записываем в нем 0. Убедитесь, что вы не добавляете никаких пробелов до или после 0.
Второе, что следует отметить, это то, что число выровнено слева, в то время как калькуляторы выравнивают число справа. Найдите свойство TextAlign и измените его на Right.
Вот как будет выглядеть окно.
В окне панели инструментов перетащите кнопку на форму. Измените его свойство Name на n1. Это поможет нам определить, какой номер был нажат. Измените свойство backcolor для кнопки. После изменения цвета мы изменим текст, отображаемый кнопкой, поэтому измените свойство text на 1. Перейдите к свойству шрифта и установите для него значение шрифта Сourier new, а размер, например, 16.
Теперь мы можем повторить ту же операцию со всеми остальными девятью кнопками, или мы можем просто скопировать эту кнопку и быстро получить тот же результат. Просто удерживайте клавишу ctrl и перетащите элемент управления.
Измените названия кнопок (или вы можете оставить их как есть и пропустить эту часть). Имена по-прежнему будут n2, n3, n4, n5, n6, n7, n8, n9 и n0.Окно должно выглядеть так.
Дважды нажмите кнопку n1, чтобы перейти к ее обработчику события. Тогда n1_Click — это название этой процедуры. Он сообщает вам, что он выполняется, когда пользователь нажимает кнопку с именем n1. Запишите код, чтобы он был таким:
private void n1_Click(object sender, EventArgs e)
<
if (textBox1.Text == "0" && textBox1.Text != null)
<
textBox1.Text = "1";
>
else
<
textBox1.Text = textBox1.Text + "1";
>
>
Вы должны повторить код для кнопок n2, n3, n4, n5, n6, n7, n8, n9 и n0, чтобы добавить числа 2,3,4,5,6,7,8,9,0 соответственно.
Теперь запустите приложение и нажмите несколько кнопок:
Таким образом, мы создали простой шаблон калькулятора с C# и Windows Forms, в который осталось добавить арифметическую логику.
Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!
Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.
Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления
Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.
Порекомендуйте эту статью друзьям:
Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):
Она выглядит вот так:
Комментарии ( 0 ):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.
Пишем «калькулятор» на C#. Часть I. Вычисление значения, производная, упрощение, и другие гуси
Калькулятор у нас почему-то ассоциируется с чем-то, что должен написать каждый новичок. Возможно потому, что исторически компьютеры с той целью и создавались, чтобы считать. Но мы будем писать непростой калькулятор, не sympy конечно, но чтобы умел базовые алгебраические операции, типа дифференциирования, симплификации, а также фичи типа компиляции для ускорения вычислений.
Сборка выражения
Что такое «выражение»?
Конечно, это не строка. Довольно очевидно, что математическая формула — это либо дерево, либо стек, и здесь мы остановимся на первом. То есть каждая нода, каждый узел этого дерева, это какая-то операция, переменная, либо константа.
Операция — это либо функция, либо оператор, в принципе, примерно одно и то же. Ее дети — аргументы функции (оператора).
Иерархия классов в вашем коде
Разумеется, реализация может быть любой. Однако идея в том, что если ваше дерево состоит только из узлов и листьев, то они бывают разными. Поэтому я называю эти «штуки» — сущностями. Поэтому верхним классом у нас будет абстрактный класс Entity.
А также будет четыре класса-наследника: NumberEntity, VariableEntity, OperatorEntity, FunctionEntity.
Как построить выражение?
Для начала мы будем строить выражение в коде, то есть
Если объявить пустой класс VariableEntity, то такой код выкинет вам ошибку, мол не знает как умножать и суммировать.
Переопределение операторов
Очень важная и полезная фича большинства языков, позволяя кастомизировать выполнение арифметических операций. Синтаксически реализуется по-разному в зависимости от языка. Например, реализация в C#
(Не)явное приведение типов
В компилируемых языках типа C# такая штука обычно присутствует и позволяет без дополнительного вызова myvar.ToAnotherType() привести тип, если необходимо. Так, например, было бы удобно писать
Подвешивание
Класс Entity имеет поле Children — это просто список Entity, которые являются аргументами для данной сущности.
Вообще-то детей могут иметь объекты лишь двух классов: OperatorEntity и FunctionEntity. То есть в принципе можно было бы создать какой-нибудь NodeEntity и у него унаследовать эти два класса, и создать LeafEntity и от него унаследовать VariableEntity и NumberEntity.
Когда у нас вызывается функция или оператор, нам стоит создать новую сущность, и в ее дети положить то, от чего вызывается функция или оператор. К примеру, сумма по идее должна выглядить примерно так:
То есть теперь если у нас есть сущность x и сущность 3, то x+3 вернет сущность оператора суммы с двумя детьми: 3 и x. Так, мы можем строить деревья выражений.
Вызов функции более простой и не такой красивый, как с оператором:
Подвешивание в репе реализовано тут.
Отлично, мы составили дерево выражений.
Подстановка переменной
Здесь все предельно просто. У нас есть Entity — мы проверяем является ли он сам переменной, если да, возвращаем значение, иначе — бежим по детям.
В этом огромном 48-строчном файле реализована столь сложная функция.
Вычисление значения
Собственно то, ради чего все это. Здесь мы по идее должны добавить в Entity какой-то такой метод
Листик без изменений, а для всего остального у нас кастомное вычисление. Опять же, приведу лишь пример:
Если аргумент — число, то произведем численную функцию, иначе — вернем как было.
Number?
Это самая простая единица, число. Над ним можно проводить арифметические операции. По умолчанию оно комплексное. Также у него определены такие операции как Sin, Cos, и некоторые другие.
Если интересно, Number описан тут.
Производная
Численно производную посчитать может кто угодно, и такая функция пишется поистине в одну строку:
Но разумеется нам хочется аналитическую производную. Так как у нас уже есть дерево выражений, мы можем рекурсивно заменить каждый узел в соответствии с правилом дифференциирования. Работать оно должно примерно так:
Вот, к примеру, как реализованна сумма в моем коде:
А вот произведение
А вот сам по себе обход:
Это метод Entity. И как видим, что у листа всего два состояния — либо это переменная, по которой мы дифференциируем, тогда ее производная равна 1, либо это константа (число либо VariableEntity), тогда ее производная 0, либо узел, тогда идет отсылка по имени (InvokeDerive обращается к словарю функций, где и находится нужная (например сумма или синус)).
Заметьте, я здесь не оставляю что-то типа dy/dx и сразу говорю, что производная от переменной не по которой мы дифференциируем равна 0. А вот здесь сделано по-другому.
Все дифференциирование описано в одном файле, а больше и не надо.
Упрощение выражения. Паттерны
Упрощение выражения в общем случае в принципе нетривиально. Ну например, какое выражение проще: или ? Но мы придерживаемся каких-то представлений, и на основе них хотим сделать те правила, которые точно упрощают выражение.
Можно при каждом Eval писать, что если у нас сумма, а дети — произведения, то переберем четыре варианта, и если где-то что-то равно, вынесем множитель… Но так делать конечно же не хочется. Поэтому можно догадаться до системы правил и паттернов. Итак, что мы хотим? Примерно такой синтаксис:
Вот пример дерева, в котором нашлось поддерево (обведено в зеленый), отвечающее паттерну any1 + const1 * any1 (найденное any1 обведено в оранжевый).
Как видим, иногда нам важно, что одна и та же сущность должна повторяться, например чтобы сократить выражение x + a * x нам необходимо, чтобы и там и там был x, ведь x + a * y уже не сокращается. Поэтому нам нужно сделать алгоритм, который не только проверяет, что дерево соответсвует паттерну, но и
- Проверять, что одинаковые паттерновые Entity соответствуют одинаковым Entity.
- Записывать, что чему соответствует, чтобы потом подставить.
А в tree.PaternMakeMatch мы рекурсивно наполняем словарь ключами и их значениями. Вот пример списка самих паттерных Entity:
Когда мы будем писать any1 * const1 — func1 и так далее, у каждой ноды будет номер — это и есть ключ. Иначе говоря, при заполнении словаря, ключами выступят как раз эти номера: 100, 101, 200, 201, 400… А при постройке дерева мы будем смотреть на значение, соответствующее ключу, и подставлять его.
Упрощение. Сортировка дерева
В статье, к которой я уже обращался, автор решил сделать просто, и отсортировал практически по хешу дерева. Ему удалось сократить a и -a, b + c + b превратить 2b + c. Но мы, конечно, хотим и чтобы (x + y) + x * y — 3 * x сокращалось, и в целом более сложные штуки.
Паттерны не работают?
Вообще, то, что мы сделали до этого, паттерны — чудовищно замечательная штука. Она позволит вам сокращать и разность квадратов, и сумму квадрата синуса и косинуса, и другие сложные штуки. Но элементарную пальму, ((((x + 1) + 1) + 1) + 1), она не сократит, ведь здесь главное правило — коммутативность слагаемых. Поэтому первый шаг — вычленить «линейных детей».
«Линейные дети»
Собственно для каждой ноды суммы или разности (и, кстати, произведения/деления) мы хотим получить список слагаемых (множителей).
Это в принципе несложно. Пусть функция LinearChildren(Entity node) возвращает список, тогда мы смотрим на child in node.Children: если child — это не сумма, то result.Add(child), иначе — result.AddRange(LinearChildren(child)).
Не самым красивым образом реализовано тут.
Группировка детей
Итак, у нас есть список детей, но что дальше? Допустим, у нас есть sin(x) + x + y + sin(x) + 2 * x. Очевидно, что наш алгоритм получит пять слагаемых. Далее мы хотим сгруппировать по похожести, например, x похож на 2 * x больше, чем на sin(x).
Вот хорошая группировка:
Так как в ней паттерны дальше справятся с преобразованием 2*x + x в 3*x.
То есть мы сначала группируем по некоторому хешу, а затем делаем MultiHang — преобразование n-арного суммирования в бираное.
Хеш узла
С одной стороны, и следует поместить в одну группу. С другой стороны, при наличии помещать в одну группу с бессмысленно.
Поэтому мы реализовываем многоуровневую сортировку. Сначала мы делаем вид, что — одно и то же. Посортировали, успокоились. Потом делаем вид, что можно помещать только с другими . И вот уже наши и наконец объединились. Реализовано достаточно просто:
Как видим, функция по-любому влияет на сортировку (разумеется, ведь с вообще никак в общем случае не связана). Как и переменная, с ну никак не получится смешать. А вот константы и операторы учитываются не на всех уровнях. В таком порядке идет сам процесс упрощения
«Компиляция» функций
В кавычках — так как не в сам IL код, а лишь в очень быстрый набор инструкций. Но зато очень просто.
Проблема Substitute
Чтобы посчитать значение функции, нам достаточно вызвать подстановку переменной и eval, например
Но это работает медленно, около 1.5 микросекунды на синус.
Инструкции
Чтобы ускорить вычисление, мы делаем вычисление функции на стеке, а именно:
1) Придумываем класс FastExpression, у которого будет список инструкций
2) При компиляции инструкции складываются в стек в обратном порядке, то есть если есть функция x * x + sin(x) + 3, то инструкции будут примерно такими:
Далее при вызове мы прогоняем эти инструкции и возвращаем Number.
Пример выполнения инструкции суммы:
Вызов синуса сократился с 1500нс до 60нс (системный Complex.Sin работает за 30нс).
В репе реализовано тут.
Фух, вроде бы пока все. Хотя рассказать еще есть о чем, но мне кажется объем для одной статьи достаточный. Интересно ли кому-нибудь продолжение? А именно: парсинг из строки, форматирование в латех, определенный интеграл, и прочие плюшки.
Calculator in Windows Form using C#
These WinForms provide a platform to App developers to write rich client applications for laptop, desktops, and tablet PCs etc.
These WinForms are written in C# programming
Language and an attractive feature included in it is the drag and drop facilities that can be applied on the native Windows Controls like button , textbox, checkbox, listview etc
These controls included in uncountable number of applications. One of the application that we will study about is Calculator made in Windows Forms.
So let us quickly get started to make our own basic calculator in WinForms.
STEP 1: Open Visual Studio or the IDE which you are comfortable with and create a new project . Select the Windows Form Application that comes under .net framework.
Click on create and then name the project as per your choice, for eg. “Calculator_1” and then press OK.
A main form on your workspace will appear as this:
STEP 2: Right click on the form and select “properties” from the dialog box and then change the text property to “calculator” for your convenience.
Also, you can modify the size of the form by adjusting its property attributes.
STEP 3: Open toolbox by pressing Ctrl + Alt + X or from the view in Menu Bar if toolbox is not there on the workspace already.
- Once you come across the toolbox , select “textbox“ control and drop it onto the form. Resize it according to your need from the properties or you can adjust it directly by the arrows that appear on the textbox boundary once you click on the textbox.
- This textbox will display the values selected by the user and the result generated by the calculator.
- Change the alignment of the text in the textbox to right in the properties. You can also set the default value in calculator textbox to 0.
STEP 4: A basic calculator will contain numerical digits from 0 to 9, + , — , * , /, . , = . Also ON ,OFF buttons for turning the calculator on and off and vice versa. Two additional buttons namely “clear” and “<=” (backspace) are added if any value is to be removed from the textbox .
Therefore, we will be adding 20 buttons in the form. Please note that we will add the ON and OFF button in such a way that one button overlaps the other. This is to make any one button out of these two to be visible when the calculator is on or off. i. e , the ON button will be hidden when we turn it on and the OFF button will be shown and vice versa.
STEP 5: Select “ button control” from the toolbox and resize it. Copy and paste this button on the form for all the other buttons on the calculator to maintain symmetry in the calculator.
Adjust the “=” button size as according to the picture here.
STEP 6: Name these buttons according to the function they are performing . for eg. For numerical values , name them as “ b0 to b9 ” for 0 to 9. For + , — ,* ,/ ,= ,. , change name to add , sub , mul , div, result, point respectively.
Also change their text according to the values that are to be displayed on the buttons in the calculator.
STEP 7: Once it is done , you will have to specify the action that has to be performed by any button when it is pressed. Double click on the button you will come across the coding section of that button. You have to specify the functionality of each button one by one in the code section.