在工程项目中,通常基于C#的winform或WPF设计开发上位机界面,实现系统的统一协调控制。C#是完全面向对象的语言,所谓完全面向对象,是相对于C++而言的,后者还兼容了C语言中的函数定义。前者则全部是类对象的概念。
强烈推荐刘铁猛老师的《C#入门详解》,深入浅出,逻辑通畅,受益匪浅。
基于winform,简易计算器界面如下:
按键可以分为四类:
- 数字按键:0~9
- 运算符:+、-、*、/
- 数值功能:±数值切换,和小数点.
- 结果运算和控制:=:计算表达式的值、CE:清空结果为“0”,Del:删除表达式最后一位
基于计算器的运算步骤和逻辑:
数字按键0~9的功能一致,所以可以利用事件委托统一处理;
同理,四则运算符功能一致,可利用另一事件委托统一处理。
其余的按键:=、±、CE、Del等根据其事务逻辑进行相应编程处理即可。
数字、运算符事件委托代码示例:
功能性按键的标志位定义:
数字按键事件函数定义:
private void Numbers_Click(object sender, EventArgs e)
{
string strClickNum = ((Button)sender).Text;
try
{
if (DotClicked)
{
//得出点击的小数数值
//decimalIndex++;
DecimalNum *= 0.1;
checked { NumTemp = NumTemp + long.Parse(strClickNum) * DecimalNum; }
}
else
{
checked { NumTemp = NumTemp * 10 + long.Parse(strClickNum); }
}
}
catch
{
MessageBox.Show("数据溢出");
}
if (!Flag) //将这两个if语句交换顺序,结果是不一样的 就像穿袜子和穿鞋的顺序
{
txtOutput.Text += strClickNum;
}
if (Flag)
{
Flag = false;
Flag_Char = false;
if (Flag_Dot)
{
txtOutput.Text += strClickNum;
}
else
{
txtOutput.Text = strClickNum;
}
}
Flag_Inverse = false;
// DotClicked = false; //小数点的标志位只能在等于号与清除号中置位
}
运算符事件函数定义:
private void Operators_Click(object sender, EventArgs e)
{
string strClickOp = ((Button)sender).Text;
cOperator = strClickOp[0];//strClickOp长度为1 如何将string转换为char
if (Flag) //当enter键按下时,将计算结果作为第一个计算数
{
if (!Flag_Inverse)
{
NumFormer = double.Parse(txtOutput.Text);
}
}
else
{
if (!Flag_Char)
{
if (!Flag_Inverse)
{
NumFormer = double.Parse(txtOutput.Text);
}
}
}
NumTemp = 0; //按下符号键都会置零
if (!Flag_Char)
{
Flag_Char = true;
txtOutput.Text += cOperator.ToString();
}
if (Flag_Char)//改变运算符号
{
//MessageBox.Show(txtOutput.Text);
txtOutput.Text = txtOutput.Text.Substring(0, txtOutput.Text.Length - 1) + cOperator.ToString();
}
DotClicked = false;
DecimalNum = 1;
Flag = false;
Flag_Dot = false;
Flag_Inverse = false;
}
部分功能性按键代码示例:
// =
private void button_enter_Click(object sender, EventArgs e)
{
try
{
//MessageBox.Show(NumFormer.ToString() + "__" + NumTemp.ToString());
switch (cOperator)
{
case '+':
checked { Result = NumFormer + NumTemp; }
break;
case '-':
checked { Result = NumFormer - NumTemp; }
break;
case '*':
checked { Result = NumFormer * NumTemp; };
break;
case '/':
checked { Result = NumFormer / NumTemp; };
break;
}
}
catch
{
MessageBox.Show("运算结果溢出");//自动弹窗显示
}
Flag = true; //enter键按下
Flag_Char = false; //符号键还没按下
Flag_Dot = false;
Flag_Inverse = false;
DotClicked = false;
txtOutput.Text = Result.ToString();
//清空变量
NumFormer = double.Parse(txtOutput.Text);
NumTemp = 0;//临时变量
cOperator = '\0';//操作符
DecimalNum = 1;
}
// CE
private void button_ce_Click(object sender, EventArgs e)
{
//清空变量
NumFormer = 0;//前一个操作数
NumTemp = 0;//临时变量
Result = 0;//结果
cOperator = '\0';//操作符
DecimalNum = 1;
//清空页面显示
txtOutput.Text = "0";
Flag = true;
Flag_Char = false;
Flag_Dot = false;
Flag_Inverse = false;
DotClicked = false;
}
本代码的特点在于可以实现连续计算,即将上次运算结果作为本次计算的操作数,同时提供“±”实现数值取反,以及Del实现错误字符的删除,从而方便计算。简易计算器运行结果如下,起始的两个操作数取自潘多拉魔盒:996—007。
简易计算器
本代码是事件委托的简单应用,简易地实现连续计算,未进行详尽全面的计算测试,问题和错误在所难免,欢迎大家批评指正。
基于表达式树的复杂表达式一次性计算,有待后面实现。
完整代码可参考:[github]