课 程 设 计
课程名称: C#课程设计
设计课题: 简单计算器的设计与实现
二O二三年 十二 月十一日
C#课程设计
设计要求 (1)分组后,每组抽取一个题目,每人完成该题目
的一个功能模块的设计;
(2)winform应用程序实现(代码须锯齿型书写格式);
(3)必须上机调试通过;
(4)每人单独完成一份完整的课程设计报告。
课 题 发 给 日 期 2023年11月30日
1、程序功能菜单等界面设计情况:
2、功能全面,是否达到设计要求:
3、答辩情况:
4、课设报告完成情况:
5、出勤情况:
评分:
《C#课程设计》
任务书
二○二三年十二月
一、课程设计目的
C#课程设计是计算机类专业本科专业的集中实践性环节之一,是学习完《C#程序设计》课程后进行的一次全面综合应用练习。目的是要达到理论与实际相结合,使学生能针对现实世界中的实际问题设计C# winform应用程序,培养良好的程序设计技能并为后续课程学习打下基础。
课程设计中,要求学生通过 C#语言来设计与实现简单应用程序。查阅相关资料,根据应用程序的需求进行各阶段设计,编码实现一个相对完整的、具有一定实用价值的功能模块,并以文本方式提交课程设计报告。
在课程设计中可能用到一些教学中未涉及的知识,学生查阅相关文献资料,也可自学必要的内容,教师做出相应指导。学生设计过程中,教师应对每一位学生的学习态度、实践能力以及进度把握等应做到心中有数。
二、课程设计日期、时间、地点
1、日期:2023年11月30日--12月11日(周末除外)
2、地点:D404
4、答辩时间:15周周一开始。
三、注意事项
1、允许并鼓励同学之间相互讨论。
2、允许参考文献、网络上的资源,但严禁全盘复制。
3、严禁旷课,有事凭辅导员批准的假条请假。。
4、保持机房卫生,保持工作环境清洁;
5、爱护机房设备,如有损坏照价赔偿。
四、课程设计要求
1.使用C#语言,完成功能设计,按照网站需求分析、概念结构设计、数据库设计与实施、界面设计与实现、代码编写、测试与修正等流程进行,所设设计的模块必须能够正常运行,并实现所要求的功能。
2. 课程设计要求独立完成,不得抄袭。发现抄袭行为成绩一律记零分。
3. 课程设计结束时,需每人提交《课程设计报告》一份。课程设计报告以word 编辑,A4纸双面打印,装订后提交。同时提交程序源代码的电子文档(以小组长的学号+姓名命名)。
3、承担同一项目开发任务的小组成员,每人所从事的程序开发工作(程序模块)应有明确分工,不可有重复部分
4.课程设计评分标准:
(1)出勤 20分(旷课3次及以上,不合格直接重修);
(2)程序设计完成情况 50分 (答辩成绩25分+代码检查25分);
(3)课程设计报告30分。
五、课程设计题目及分工
本次设计根据抽选的题目供同学练习。分工后,不允许自行调换。
计算器的开发与应用
摘要:计算器是一种常见的应用程序,用于执行数学运算和表达式求值。它可以用于简单的日常计算,也可以在科学、工程和金融等领域进行复杂的计算。计算器的产生和发展是建立在电子计算机基础之上的,现代社会很需要一个健全、高效率的计算器。为了提高自己的实践能力和将来开发一个更实用,更全能更智能的计算器,以设计与实现计算器为课题。此次设计的计算器应用软件从visual studio2022编程环境中开发,是一个简单的窗体应用程序,实现简单的计算器功能。以微软自带的计算器为模板,设计了简单易懂的计算器。这款计算器不仅实现了简单的四则运算的功能,还能连续运算,实现小键盘的操作,光标的转移。虽然这个简单的计算器只能实现这些功能,但是具有简洁的图文外观,即时准确的获得所需要要计算的结果,充分降低了数字计算器的难度和所需要的时间,对人们生活和学习具有有很大的帮助。
关键词:计算器;功能;界面;窗口;事件。
附一:本人完成界面设计、窗口切换、表达式显示等功能模块设计... 31
1.需求分析
通过对微软附件计算器软件进行调研、分析,研究,使用。我们小组了解到了作为一个计算器所应该有的一些简单功能和界面的排版,我们知道了怎样使编写的计算器程序向微软附件计算器靠拢。
1.1 实验目的
设计一个简单计算器,在功能上功能尽量模拟windows操作系统中的计算器,系统界面不做强制要求,实现加、减、乘、除、求开方、求倒数等功能,实现进制间的转换功能:十进制、二进制、十六进制、八进制。
其他要求:应具有一般计算功能,能进行基本的加减乘除运算。其他计算功能作为加分项。界面美观,功能丰富。开发平台:VS2010及以上,团队人数:4人。
1.2计算器应用软件的功能分析
计算器软件的主要功能是:
1)可以显示计算数字的多项式。
2)可以进行加减乘除四则运算,和开方、取余、求倒数等功能。
3)可以进行算术表达式优先级的关系进行求值。
4)可以进行窗口切换
5)可以进行十进制、二进制、十六进制、八进制之间互相转换。
6)可以进行大数据运算不会出现溢出错误。
1.3 计算器软件的功能图
根据以上需求分析,实现了主要的功能,计算器软件功能如图1-1所示。
图 1-1
2.界面设计
计算器软件界面设计采用两个form窗口,一个主要实现计算器的功能,另一个实现进制转换的功能。使用多个button按钮用于获取表达式的输入以及窗口之间的切换,和多个texbox文本框显示进制转换的结果。完成界面如图2-1、2-2。
图 2-1
图 2-2
2.1窗口切换
代码运行之后首次显示的页面为计算器软件的主界面,主界面上方的两个button既有显示功能又有点击事件功能。
左上方button按钮主要显示计算表达式,其次实现计算器主界面跳转到进制转换窗口界面。
主界面右上方主要显示最终的值,其次点击右上方的button按钮会显示表达式最终的结果。
窗口切换的核心代码:
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();//想要打开的窗体界面
this.Hide();//隐藏当前窗体
frm2.ShowDialog();
Application.ExitThread(); //退出当前窗体,这一步很重要,否则最后可能无法将所有进程关闭。最好是在跳转页面后,将之前的页面退出。
}
3.功能实现
要实现需求分析中软件各功能,需要设计一些事件的功能代码。利用所需的
代码,编写一些计算器的功能,使计算器更加灵活易懂。
3.1表达式显示的主要代码
表达式分为两种:一种是没有包含开方的表达式,另一种是包含开方的表达式。
主要实现代码如下:
if (radication == "") //判断是否含有开方表达式
{
string temp;
string firstStr = showRes.Text.Substring(0, showRes.Text.Length - 1);
string lastStr = showRes.Text.Substring(showRes.Text.Length - 1);
temp = (Math.Sqrt(Convert.ToDouble(lastStr))).ToString();
//含有开发表达式
radication = firstStr +""+ temp;
showRes.Text = firstStr + ("√" + lastStr).ToString();
}
else
{
string temp;
string firstStr = radication.Substring(0, radication.Length - 1);
string ffirstStr = showRes.Text.Substring(0, showRes.Text.Length - 1);
string lastStr = showRes.Text.Substring(showRes.Text.Length - 1);
temp = (Math.Sqrt(Convert.ToDouble(lastStr))).ToString();
radication = radication+ showRes.Text.Substring(showRes.Text.Length - 2,1) +temp;
showRes.Text = ffirstStr + ("√" + lastStr).ToString();
}
3.2添加数字和运算符
判断是数字还是字符,主要代码如下:
public void AppendNumber(string num)
{
string vaildStr = ".,0,1,2,3,4,5,6,7,8,9";
if(vaildStr.IndexOf(num)>= 0)
{
//说明是数字
showRes.Text += num;
GlobalExpression += num;
//radication += num;
}
else
{
//说明是符号
if (GlobalExpression != "")
{
string A_ZStr = "A,B,C,D,E,F";
if (A_ZStr.IndexOf(num) >= 0)
{
//说明是数字
showRes.Text += num;
GlobalExpression += num;
//radication += num;
}
//第一次算法
String lastStr=GlobalExpression.Substring(GlobalExpression.Length-1,1);
if (vaildStr.IndexOf(lastStr) >= 0)
{
showRes.Text += num;
GlobalExpression = Operation(num);
}
}
//GlobalExpression = "需要先填写数字";
}
//showRes.Text = GlobalExpression;
//Expression.Text = GlobalExpression;
}
图 3-1
3.3清零运算功能代码
使用清零功能键,所有用于显示的值和运算的值都将会被清空。
主要代码如下:
private void Clear_Click(object sender, EventArgs e)
{
GlobalExpression = "";
Expression.Text = "";
showRes.Text = "";
radication = "";
}
3.4求倒数功能
输入一个数字,可以快速求出一个数字的倒数。
主要功能代码如下:
private void Rec_Click(object sender, EventArgs e)
{
string temp;
string firstStr = showRes.Text.Substring(0, showRes.Text.Length - 1);
string lastStr = showRes.Text.Substring(showRes.Text.Length - 1);
showRes.Text = firstStr+(1 + "/"+ lastStr).ToString();
}
//需改善的地方,最初设计的时候只考虑到了个位数求倒数,如需多位数求倒数,只需添加一个判断语句。
图 3-2
3.5求值功能代码
主界面右上方button按钮主要的事件功能
其主要代码如下:
private void Expression_Click(object sender, EventArgs e)
{
try
{
double result = 0;
char[] post = new char[100];
if (radication != "")
{
string temp;
//string message = $"根号:{radication}";
//MessageBox.Show("根号表达式"+ message);
AnalyExpression.postfix(radication + '#', post);
temp = AnalyExpression.postfixValue(post).ToString();
showRes.Text += "=";
//AnalyExpression.AnalyExpressions(radication, out result);
GlobalExpression = result.ToString();
Expression.Text = temp;
//Expression.Text = radication.ToString();
}
else
{
string temp;
AnalyExpression.postfix(showRes.Text + '#', post);
temp = AnalyExpression.postfixValue(post).ToString();
showRes.Text += "=";
GlobalExpression = result.ToString();
Expression.Text = temp;
}
}
catch (Exception)
{
return;
}
}
图 3-3
3.6多项式表达式算法逻辑
多项式表达式算法逻辑是整个软件的核心代码,所有计算都是依赖此代码进行计算的。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace 计算器测试
{
internal class AnalyExpression
{
//栈外优先数
public static int icp(char ch)
{
switch (ch)
{
case '#':
return 0;
case '(':
return 10;
case '+':
case '-':
return 2;
case '*':
case '/':
case '%':
return 4;
case '√':
case 't':
case 's':
case 'c':
case 'L':
case '^':
return 8;
case ')':
return 1;
}
return -1;
}
//栈内优先数
public static int isp(char ch)
{
switch (ch)
{
case '#':
return 0;
case '(':
return 1;
case '+':
case '-':
return 3;
case '*':
case '/':
case '%':
return 5;
case '√':
case 't':
case 's':
case 'c':
case 'L':
case '^':
return 9;
case ')':
return 10;
}
return -1;
}
//判断操作符
public static bool isOperator(char op)
{
switch (op)
{
case '+':
case '-':
case '*':
case '/':
case '%':
case '(':
case ')':
case '√':
case 't':
case 's':
case 'c':
case 'L':
case '^':
return true;
default:
return false;
}
}
//中缀转后缀
public static void postfix(string e, char[] post)
{
int i = 0;
int j = 0;
Stack<char> st = new Stack<char>();
st.Push('#'); //将‘#’结束标识符塞入栈底
while (e[i] != '#')
{
if ((e[i] >= '0' && e[i] <= '9') || e[i] == '.') //遇到数字和小数点直接写入后缀表达式
{
post[j++] = e[i];
}
else if (isOperator(e[i]))
{
post[j++] = ' '; // 用空格分开操作数
while (isp(st.Peek()) > icp(e[i]))
{
post[j++] = st.Pop();
}
if (isp(st.Peek()) == icp(e[i]))
{
st.Pop();
}
else
{
st.Push(e[i]);
}
}
i++;
}
while (!st.Count().Equals(0)) // 将所有的操作符加入后缀表达式
{
post[j++] = st.Pop();
}
}
//获取数字
public static double readNumber(char[] str, ref int i)
{
Double x = 0.0; //用于返回数字
int k = 0; //有小数时,用于确定除以10的个数
while (str[i] >= '0' && str[i] <= '9')
{
x = x * 10 + (str[i] - '0');
i++;
}
if (str[i] == '.')
{
i++;
while (str[i] >= '0' && str[i] <= '9')
{
x = x * 10 + (str[i] - '0');
k++;
i++;
}
}
while (k != 0)
{
x /= 10;
k--;
}
return x;
}
//计算
public static double postfixValue(char[] post)
{
Stack<double> num = new Stack<double>();
int i = 0;
double x1, x2; //两个操作数
while (post[i] != '#')
{
if (post[i] >= '0' && post[i] <= '9')
num.Push(readNumber(post, ref i));
else if (post[i] == ' ')
i++;
else if (post[i] == '+')
{
x2 = num.Pop();
x1 = num.Pop();
num.Push(x1 + x2);
i++;
}
else if (post[i] == '-')
{
x2 = num.Pop();
x1 = num.Pop();
num.Push(x1 - x2);
i++;
}
else if (post[i] == '*')
{
x2 = num.Pop();
x1 = num.Pop();
num.Push(x1 * x2);
i++;
}
else if (post[i] == '/')
{
x2 = num.Pop();
x1 = num.Pop();
try
{
if(x2==0)
throw new System.DivideByZeroException();
num.Push(x1 / x2);
}
catch (DivideByZeroException)
{
MessageBox.Show("被除数不能为0", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return 0;
}
i++;
}
else if (post[i] == '%')
{
x2 = num.Pop();
x1 = num.Pop();
try
{
if (x2 == 0) throw new System.DivideByZeroException();
num.Push(x1 % x2);
}
catch (DivideByZeroException e)
{
MessageBox.Show("被除数不能为0", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
i++;
}
else if (post[i] == '^')
{
x2 = num.Pop();
x1 = num.Pop();
num.Push(Math.Pow(x1, x2));
i++;
}
else if (post[i] == 'L')
{
x1 = num.Pop();
num.Push(Math.Log(x1));
i++;
}
else if (post[i] == 'c')
{
x1 = num.Pop();
num.Push(Math.Cos(x1));
i++;
}
else if (post[i] == 't')
{
x1 = num.Pop();
num.Push(Math.Tan(x1));
i++;
}
else if (post[i] == 's')
{
x1 = num.Pop();
num.Push(Math.Sin(x1));
i++;
}
else if (post[i] == '√')
{
x1 = num.Pop();
try
{
if (x1 < 0) throw new System.DivideByZeroException();
num.Push(Math.Pow(x1, 0.5));
}
catch (DivideByZeroException)
{
MessageBox.Show("请输入正数", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return 0;
}
i++;
}
else
{
MessageBox.Show("请仔细检查表达式,如:括号对应等", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return 0;
}
}
try
{
return num.Peek();
}
catch (Exception)
{
MessageBox.Show("请仔细检查表达式,如:括号对应等", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return 0;
}
}
}
}
4.进制转换
进制转换功能实现了二进制、八进制、十进制、十六进制之间的相互转换,在软件的文本框中输入任一指定进制,其余三种进制会同时算出来。
其主要的核心代码如下:
string ConvertTo(string number, int sourceBase, int targetBase)
{
try {
long decimalValue = Convert.ToInt64(number, sourceBase);
string result = Convert.ToString(decimalValue, targetBase);
return result;
}catch {
textBox1.Text = "";
textBox2.Text = "";
textBox3.Text = "";
textBox4.Text = "";
return "";
}
}
图 4-1
5.项目总结
通过简易计算器这一程序的开发。我更进一步的了解了面向对象程序开发的过程也亲身体验了开发一个简单系统的细节点滴。通过这个例子,我对类的使用和认识有了更深入的体会。
首先这是一个计算器程序,主要的是对十进制数据的简单的四则运算操作。包含了最基本的对一些按钮和文本框的操作。了解到了这类程序的开发过程和基本入手点。可以说这是我第一次用完全的面向对象语言开发一个简单的小程序。这也让我深刻体会到了类在面向对象开发过程中的重要性和便捷之处。只有亲身体验才有真正的收获。
对于这个项目我有一些满意的地方也有感到不足的地方。其中满意的地方是这个程序实现了预计的功能知即对数据的四则运算操作、一些三倒数、开方且计算结果无误。而且我也在这个项目中用到了学到的C语言数据结构的算法逻辑的一些思想。从这点我体会到了不同程序的共通性和不同语言间的共通性。
通过这个程序我解决了窗体的应用问题。把原来只能在DOS提示符下运行的程序是现在了WINDOWS窗体中。当然知这个项目中还是存在很多不足之处的。比如这个计算器程序的计算中没有能够实现多位数的倒数和开方运算。有些地方写的代码效率不高。而且由于对程序设计不是很精通。我觉得这个项目中代码的编写也不足够规范,文档说明也不足、有些东西知道用什么思想,但就是表达不不来。
培养一个良好的编程风格是十分重要的。整齐的代码格式会大大提高程序可读性。完整的技术文档对日后维护和升级十分重要。所以在编程的细节方面我还应该多加注意。
参考文献
[1]邓英伟,袁晓红,张小琳,谭艳,彭伟. 智能系统研究[J]. 海峡科技与产业,2017(10):67-68+74.
[2]魏国利,张成刚. 基于ASP.NET框架管理系统设计与实现[J]. 信息与电脑(理论版),2017(23):121-122+125.
[3]杨晓吟. 多样化题型在线考试系统的实现[J]. 数字通信世界,2017(11):214+217.
[4]蒋玉芳. 基于ASP.NET系统的设计与实现[J]. 科技广场,2017(08):35-38.
[5]颜石,杨琨,刘杰. 预报业务在线学习考试系统设计[J]. 科技风,2018(06):6+8.
[6]郭力子,visual ci#程序设计应用教程[M机械工程出版社
[7]李兰友,杨晓光。Visual C:#程序设计[M.北京:清华大学出版社,北京交通大学出版社,2004.
附一:本人完成界面设计、窗口切换、表达式显示等功能模块设计
计算器主界面包含22个button按钮框,用于和用户进行交互设计。界面设计是计算器开发中的重要一环,它决定了用户与应用程序的交互方式和外观。一个直观、易于使用的界面可以提高用户体验并使操作更加方便。
窗口切换是指在计算器应用程序中切换不同的功能模块或视图,例如从标准计算器切换到进制转换计算器。窗口切换功能使得计算器能够提供更多功能和灵活性,满足不同用户的需求。
表达式显示功能模块负责将用户输入的数学表达式显示在计算器界面上,使用户能够清楚地看到他们输入的表达式。这对于用户检查输入的正确性和可视化计算过程非常重要。
核心代码上文已详细列出,故不多做叙述。
项目报告下载
目录
C#课程设计https://download.youkuaiyun.com/download/L152690/89248648