【课程设计|C++】C++程序设计基础:计算器(MFC)
1.设计目的和内容
1.1.设计目的
学习Visual C++的MFC开发程序的步骤。 综合运用所学的类、继承和多态的知识。 进一步掌握程序的调试方法。
1.2.设计内容
利用MFC的向导,创建基于单文档的应用程序; 实现简单的四则运算 进行科学运算,如log、tan、sin 多项式运算
2.基本功能描述
2.1.工程的新建
打开Microsoft Visual C++ 6.0
点击File —> New
在Projects中选择 MFC AppWizard (exe) ;
在 Project name中输入工程的名字Graphic,在 Location中选择工程存放的路径,填完后点击OK按钮。
(如图1)填完后点击OK按钮,弹出对话框(如图2)。
弹出来的对话框中我们可以选择生成三种不同类型的应用程序
单文档 多文档 对话框。
单文档程序如记事本,在一个应用程序中只能对一个文档进行操作,降低了编程的复杂度并减少了运行程序时所需的资源。对某些小型应用(比如文本编辑器或小型图像编辑器)可以采用这种类型的窗口应用程序。
在这个程序中,我们就需要单文档,选择完后点击Next,设置默认,最后点击Finish,
完成工程的创建。
2.2.单对话框简介
生成单文档程序后,进行编译
再运行,我们可以看到以下的结果。
2.3 界面布局
利用MFC自带的按钮、编辑框等组件,设计出计算器的初始界面。
3.设计思路
计算器的整个思想就是通过图形化界面,获取用户进行的操作和输入的数据,并按照要求进行相应的数字逻辑运算。
设计的要素就是通过按下不同的按钮,程序可以获取不同的数值,同时判断数的位置,最后通过确定键的确认,在屏幕上输出答案。
设计的难点有几个。
第一,数值的确定与传统方法不一样,比如,我们在计算器中输入123,按下的键依次是1,2,3.而每次读出的数据也是相应的单数字。
为此获取到的数字为123,我们必须设计一个算法,即每次输入数之前,先用前一次的数(第一次的数为0)乘以10,加上刚刚按下的数。
在按下符号键或复位键时,flag变换,标记是否数字输入完毕。同时符号键的设计也就是简单的为一个符号变量赋值,因为程序是固定的进行两个数的运算,只是中间的符号不同。
在这里有点区别的是,常规符号如此,科学运算符号并不如此。一般的科学运算数只有一位,所以在进行科学运算的时候,需要特别标记。
多项式运算采用的是中缀算法,也就是先对输入的多项式进行中缀变换,然后利用中缀优先级法则进行运算。这里是整个计算器设计的难点。
4.软件设计
4.1.设计步骤及关键代码
①所需变量的定义与声明
m_display2 = 0.0;
num1 = 0;
num2 = 0;
result = 0.0;
str = "";
str_flag = FALSE;
continue_flg = FALSE;
downDot = FALSE;
count = 1;
//{{AFX_DATA_INIT(CMyDlg)
m_display = _T("");
m_display1 = 0.0;
m_display2 = 0.0;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
②判断数值是否结束
double CMyDlg::buttonDownNum(int numSize)
{
if (!str_flag) //运算符没有被按下,那就是num1
{
if (!continue_flg) //按下一次
{
num1 = numSize;
continue_flg = TRUE;
}
else
{
num1 = num1 * pow(10, count) + numSize;
if (downDot)
{
num1 = num1 / (pow(10, count));
count++;
}
}
return num1;
}
else //有运算符被按下
{
if (!continue_flg) //是否连续按下
{
num2 = numSize;
continue_flg = TRUE;
}
else
{
num2 = num2 * pow(10, count) + numSize;
if (downDot)
{
num2 = num2 / (pow(10, count));
count++;
}
}
return num2;
}
}
③优先级判断
void CMyDlg::OnButton1()
{
UpdateData(true);
CString aa = m_display;
Stack<int> number; //数字栈
Stack<char> character; //运算符栈
character.Push('=');
// CString aa="1+(1*2)+2#";
int numaa = strlen(aa);
int kk = 0;
//cout<<numaa;
int ch = aa[kk++];
// int ch = getchar();
//它从标准输入里读取下一个字符。返回类型为int型,返回值为用户输入的ASCⅡ码,出错返回-1,比如输入a ,返回97,输入3,返回51
char b;
b = static_cast<char>(ch); //b是ch转换的字符
while (b != '=' || character.getTop() != '=')
{
if (ch > 48 && ch <= 57)
{ //这里非常容易写错啊!不是ch>0 && ch<=9,或者b>0 && b<=9;
number.Push(ch - 48);
ch = aa[kk++]; // getchar();
b = static_cast<char>(ch);
}
else
{
switch (Priority(character.getTop(), b))
{
case '<': //栈顶元素优先级低
character.Push(b);
ch = aa[kk++]; //getchar();
b = static_cast<char>(ch);
break;
case '=': //脱一个'('括号 并且接收下一个字符
character.Pop();
ch = aa[kk++]; //getchar();
b = static_cast<char>(ch);
break;
case '>': //出栈并且把运算结果入栈
number.Push(Compute(number.Pop(), number.Pop(), character.Pop()));
/*int result=number.Pop()+number.Pop();
cout<<result;
number.Push(result);*/
break;
}
}
}
// cout<<"运算结果是"<<" "<<number.getTop()<<'\n';
// cout<<"运算结果是:"<<number.getTop()<<endl;
//printf("运算结果是 %d \n",number.getTop());
// CString bb=CString.Format(_T("%d"),2);
m_display1 = number.getTop();
UpdateData(false);
//return 0;
}
④优先级设计
char CMyDlg::Priority(char ch1, char ch2)
{
int a;
int b;
switch (ch1)
{
case '#':
a = 0;
break;
case '(':
a = 1;
break;
case '+':
a = 3;
break;
case '-':
a = 3;
break;
case '*':
a = 5;
break;
case '/':
a = 5;
break;
case '%':
a = 5;
break;
case '^':
a = 7;
break;
case ')':
a = 8;
break;
}
switch (ch2)
{
case '#':
b = 0;
break;
case '(':
b = 8;
break;
case '+':
b = 2;
break;
case '-':
b = 2;
break;
case '*':
b = 4;
break;
case '/':
b = 4;
break;
case '%':
b = 4;
break;
case '^':
b = 6;
break;
case ')':
b = 1;
break;
}
if (a < b)
return '<';
else if (a == b)
return '=';
else
return '>';
}
⑤多项式结果运算
int CMyDlg::Compute(int a, int b, char sign)
{
int result;
switch (sign)
{
case '+':
result = a + b;
break;
case '-':
result = a - b;
break;
case '*':
result = a * b;
break;
case '/':
result = a / b;
break;
case '%':
result = a % b;
break;
case '^':
result = a ^ b;
break;
}
return result;
// TODO: Add your control notification handler code here
}
⑥常规按钮
void CMyDlg::OnButton2()
{
m_display2 = buttonDownNum(1);
UpdateData(false);
// TODO: Add your control notification handler code here
}
void CMyDlg::OnButton3()
{
m_display2 = buttonDownNum(2);
UpdateData(false);
}
void CMyDlg::OnButton4()
{
m_display2 = buttonDownNum(3);
UpdateData(false);
}
void CMyDlg::OnButton5()
{
m_display2 = buttonDownNum(4);
UpdateData(false);
}
void CMyDlg::OnButton6()
{
m_display2 = buttonDownNum(5);
UpdateData(false);
}
void CMyDlg::OnButton7()
{
m_display2 = buttonDownNum(6);
UpdateData(false);
}
void CMyDlg::OnButton8()
{
m_display2 = buttonDownNum(7);
UpdateData(false);
}
void CMyDlg::OnButton9()
{
m_display2 = buttonDownNum(8);
UpdateData(false);
}
void CMyDlg::OnButton10()
{
m_display2 = buttonDownNum(9);
UpdateData(false);
}
void CMyDlg::OnButton11()
{
m_display2 = buttonDownNum(0);
UpdateData(false);
}
void CMyDlg::OnButton13()
{
str = "+";
str_flag = TRUE;
continue_flg = FALSE;
downDot = FALSE;
count = 1;
UpdateData(FALSE);
}
⑦运算法则定义
void CMyDlg::OnButton16()
{
if (str == "+")
result = num1 + num2;
else if (str == "-")
result = num1 - num2;
else if (str == "*")
result = num1 * num2;
else if (str == "/")
{
result = double(num1) / double(num2);
}
else if (str == '^')
result = pow(num1, num2);
else if (str == 'k')
result = pow(num1, 1.0 / num2);
else if (str == 's')
result = sin(num2 * 3.1415926 / 180);
else if (str == 'c')
result = cos(num2 * 3.1415926 / 180);
else if (str == 't')
result = tan(num2 * 3.1415926 / 180);
else if (str == 'l')
result = log(num2);
else if (str == 'e')
result = exp(num2);
num1 = result;
m_display2 = result;
str_flag = FALSE;
continue_flg = FALSE;
downDot = FALSE;
count = 1;
UpdateData(FALSE);
}
编写其函数:
pCmdUI->SetCheck(shape==1); //显示 图标的样式
⑧颜色板的调用
CColorDialog Color; //定义画框
if (Color.DoModal() == IDOK)
{
m_ncolor = Color.GetColor();
}
4.2.界面设计
5.结论与心得体会
通过这次的课设,自己学到了很多,比如团队之间的合作,还有一些自己以前不是很了解的知识。
通过团队合作,可以得到很多不一样的思路,不一样的算法,每个人的思维是不一样的,所以,我们应该要吸取不同人的优点,吸收理解成自己的优点。
在这次合作的过程中,产生了很多的好点子,尽管最后有很多的功能没有实现,毕竟自己的技术还是不行,但是,有一些很好的想法也是不错了,可以锻炼我们的思维。
在这次的课设题目中,充分的将自己平时所学应用到实践中,比如栈还有java html css js等一些新语言,在这次的课设中,虽然很累,但是也还是很值得的,从刚开始的一头雾水,通过查阅资料和在老师的指导下,慢慢的懂了,慢慢的理解了其本质。希望在今后的日子里,自己的编程能力会越来越强,可以写出自己满意的代码!
6.参考文献
PDF:Windows编程基础andMFC PDF:MFC入门 PDF:深入浅出MFC
项目源码
下载路径:
结语
代码均为原创
版权归原作者所有
「仅供小伙伴们学习参考使用」
请勿用作其余用途!
创作不易
如果您觉得写的不错的话
「点赞+在看+收藏」 ❤️