运行结果:
界面采用easyx图形包,运行前需要下载easyx
源码:
#include
#include
#include
#include
#include
#include
#define OK 1
#define ERROR 0
/* 定义结点结构体 */
typedef struct node
{
int data; //数据域
struct node* next; //指针域
}Node;
/* 定义栈结构体 */
typedef struct stack
{
Node* top; //栈顶标记
int count; //栈内计数器
}Stack;
int Priority(char s);//自定义优先级
int InitStack(Stack* S); //初始化栈
int EmptyStack(Stack* S);//判空
int GetTop(Stack* S); //获取栈顶
int Push(Stack* S, int e); //进栈
int Pop(Stack* S); //出栈
void Paint(); //页面绘制
double dis(int x1, int y1, int x2, int y2);
int main()
{
Paint();
}
/* 自定义优先级 */
int Priority(char s)
{
switch (s)
{
case '(': //括号优先级最高
return 3;
case '*':
case '/':
case '%':
case '^': //乘除取余幂次次之
return 2;
case '+':
case '-': //加减最低
return 1;
default:
return 0;
}
}
/* 初始化栈 */
int InitStack(Stack* S)
{
S->top = NULL;
S->count = 0;
return OK;
}
/* 判空 */
int EmptyStack(Stack* S)
{
return (S->count == 0) ? OK : ERROR;
}
/* 获取栈顶 */
int GetTop(Stack* S)
{
if (NULL == S->top)
return ERROR;
return (S->top->data);
}
/* 进栈 */
int Push(Stack* S, int e)
{
Node* p = (Node*)malloc(sizeof(Node)); //创建新结点p
if (p == NULL) //判断是否申请成功
{
return ERROR;
}
p->data = e; //初始化
p->next = S->top; //头插法
S->top = p;
S->count++; //计数器加1
return OK;
}
/* 出栈 */
int Pop(Stack* S) //出栈返回一个操作数或者是运算符
{
int e;
if (NULL == S->top) //栈空无法出栈
return ERROR;
Node* p = S->top;
e = p->data;
S->top = p->next;
free(p);
S->count--; //计数器减一
return e;
}
void Paint() {
int number;
// 初始化图形模式
initgraph(300, 600); //初始化一个300*600的画布
// 设置背景为深灰色
setbkcolor(RGB(51, 51, 51)); //设置背景为深灰色
int c;
for (int y = 0; y < 20; y++) {
setcolor(RGB(51, 51, 51)); //设置线条颜色为灰色
line(0, y, 400, y); //用循环语句画平行直线Line(x1,y1)(x2,y2)为直线的两个端点的坐标
}
//设置文本颜色
settextcolor(WHITE); //设置当前文字颜色
//输出文本信息
settextstyle(20, 10, L"宋体");//字体的宽+字体的高+字体样式
//输出文本信息
outtextxy(10, 0, L"计算器");//文本坐标+文本内容(在指定位置输出字符串)
settextstyle(40, 0, L"黑体");
setbkmode(TRANSPARENT); //这个函数用于设置当前设备图案填充和文字输出时的背景模式。背景是透明的。
//画橙色圆
setcolor(RGB(220, 95, 8));//设置前景颜色
setfillcolor(RGB(220, 95, 8)); //设置充填颜色
setbkcolor(BLACK); //背景颜色
fillcircle(255, 550, 30); //画有边框的充填原圆(x,y,z)为坐标
settextcolor(WHITE); //设置当前文字颜色
outtextxy(245, 533, L"=");
setcolor(RGB(247, 143, 0));
setfillcolor(RGB(247, 143, 0));
setbkcolor(BLACK);
settextcolor(WHITE);
fillcircle(255, 480, 30);
outtextxy(245, 463, L"+");
fillcircle(255, 410, 30);
outtextxy(245, 393, L"-");
fillcircle(255, 340, 30);
settextstyle(30, 0, L"黑体");
outtextxy(240, 325, L"×");
fillcircle(255, 270, 30);
outtextxy(240, 255, L"÷");
//画深色圆
setcolor(RGB(51, 51, 51));
setfillcolor(RGB(51, 51, 51));
setbkcolor(BLACK);
//右边
settextcolor(WHITE);
settextstyle(40, 0, L"黑体");
fillcircle(185, 550, 30); //圆
outtextxy(180, 530, L")");
fillcircle(185, 480, 30);
outtextxy(175, 460, L"3");
fillcircle(185, 410, 30);
outtextxy(175, 390, L"6");
fillcircle(185, 340, 30);
outtextxy(175, 320, L"9");
/*fillcircle(185, 270, 30);*/
//中间
fillcircle(115, 550, 30);
outtextxy(105, 530, L"0");
fillcircle(115, 480, 30);
outtextxy(105, 460, L"2");
fillcircle(115, 410, 30);
outtextxy(105, 390, L"5");
fillcircle(115, 340, 30);
outtextxy(105, 320, L"8");
//左边
fillcircle(45, 550, 30);
outtextxy(35, 530, L"(");
fillcircle(45, 480, 30);
outtextxy(35, 460, L"1");
fillcircle(45, 410, 30);
outtextxy(35, 390, L"4");
fillcircle(45, 340, 30);
outtextxy(35, 320, L"7");
//画浅色圆
setcolor(RGB(165, 165, 165));
setfillcolor(RGB(165, 165, 165));
setbkcolor(BLACK);
settextcolor(WHITE);
fillcircle(185, 270, 30);
outtextxy(175, 252, L"%");
fillcircle(115, 270, 30);
settextstyle(40, 0, L"黑体");
outtextxy(105, 265, L"^");
fillcircle(45, 270, 30);
outtextxy(20, 255, L"√");
/*Stack num, opt;*/
char str[100] = { 0 };
int i = 0, tmp = 0, j;
int count = 0;
MOUSEMSG m;
int temp = 0, k = 255, go = 0;
//设置文本颜色
settextcolor(WHITE);
//设置文本样式
settextstyle(40, 0, L"黑体");//字体的宽+字体的高+字体样式
while (go == 0)
{
m = GetMouseMsg();
switch (m.uMsg)
{
case WM_LBUTTONDOWN:
while (dis(m.x, m.y, 255, 550) > 30)
{
if (dis(m.x, m.y, 45, 480) <= 30) {
str[i] = '1';
}
if (dis(m.x, m.y, 115, 480) <= 30) {
str[i] = '2';
}
if (dis(m.x, m.y, 185, 480) <= 30) {
str[i] = '3';
}
if (dis(m.x, m.y, 45, 410) <= 30) {
str[i] = '4';
}
if (dis(m.x, m.y, 115, 410) <= 30) {
str[i] = '5';
}
if (dis(m.x, m.y, 185, 410) <= 30) {
str[i] = '6';
}
if (dis(m.x, m.y, 45, 340) <= 30) {
str[i] = '7';
}
if (dis(m.x, m.y, 115, 340) <= 30) {
str[i] = '8';
}
if (dis(m.x, m.y, 185, 340) <= 30) {
str[i] = '9';
}
if (dis(m.x, m.y, 45, 550) <= 30) {
str[i] = '(';
}
if (dis(m.x, m.y, 115, 550) <= 30) {
str[i] = '0';
}
if (dis(m.x, m.y, 185, 550) <= 30) {
str[i] = ')';
}
if (dis(m.x, m.y, 255, 550) <= 30) {
str[i] = '=';
}
if (dis(m.x, m.y, 255, 480) <= 30) {
str[i] = '+';
}
if (dis(m.x, m.y, 255, 410) <= 30) {
str[i] = '-';
}
if (dis(m.x, m.y, 255, 340) <= 30) {
str[i] = '*';
}
if (dis(m.x, m.y, 255, 270) <= 30) {
str[i] = '/';
}
if (dis(m.x, m.y, 45, 270) <= 30) {
str[i] = '~';
}
if (dis(m.x, m.y, 115, 270) <= 30) {
str[i] = '^';
}
if (dis(m.x, m.y, 185, 270) <= 30) {
str[i] = '%';
}
/*setbkcolor(BLACK);*/
for (int y = 20; y < 200; y++) {
setcolor(BLACK);
line(0, y, 400, y);
}
settextcolor(WHITE);
for (j = 0; j <= count; j++)
{
if (count < 12) {
outtextxy(k - 20 * (count - j), 50, str[j]);
}
else if (count < 18) {
settextstyle(30, 0, L"黑体");
outtextxy(k - 15 * (count - j), 50, str[j]);
}
else {
settextstyle(20, 0, L"黑体");
outtextxy(k - 10 * (count - j), 50, str[j]);
}
}
//outtextxy(k, 50, str[i]);
Sleep(1000);
i++;
count++;
break;
}
break;
case WM_RBUTTONUP:
//go = 1;
//number = result(str);
//从这里开始是核心代码
Stack num, opt;
//申请两个栈
int i = 0, tmp = 0, j;
InitStack(&num) != OK || InitStack(&opt) != OK;
while (str[i] != '\0' || EmptyStack(&opt) != OK)
{
if (str[i] >= '0' && str[i] <= '9')
{
tmp = tmp * 10 + str[i] - '0';//可取出非个位数的数字
i++;
if (str[i] < '0' || str[i] > '9')//遇到符号就将符号前的数字压栈
{
Push(&num, tmp);
tmp = 0; //将数字初始化为0
}
}
else
{
//进栈不运算
if ((EmptyStack(&opt) == OK) || (GetTop(&opt) == '(' && str[i] != ')') ||
Priority(str[i]) > Priority(GetTop(&opt)))
{
Push(&opt, str[i]);
i++;
continue;
}
//出栈不运算
if (GetTop(&opt) == '(' && str[i] == ')')
{
Pop(&opt);
i++;
continue;
}
//出栈运算
if ((str[i] != '\0' && EmptyStack(&opt) != OK) || (str[i] == ')' && GetTop(&opt) != '(') ||
Priority(str[i]) <= Priority(GetTop(&opt)))
{
switch (Pop(&opt))
{
case '+':
Push(&num, Pop(&num) + Pop(&num));//将结果压栈
break;
case '-':
j = Pop(&num);
Push(&num, Pop(&num) - j);
break;
case '*':
Push(&num, Pop(&num) * Pop(&num));
break;
case '/':
j = Pop(&num);
Push(&num, Pop(&num) / j);
break;
case '%':
j = Pop(&num);
Push(&num, Pop(&num) % j);
break;
case '^':
j = Pop(&num);
Push(&num, pow(Pop(&num), j));
break;
case '~':
j = Pop(&num);
Push(&num, pow(Pop(&num), 0.5));
break;
}
continue;
}
}
}
//打印结果
for (int y = 150; y < 200; y++) {
setcolor(BLACK);
line(0, y, 300, y);
}
TCHAR s[10];
int Num = 0, Num1 = 0;
Num1 = Pop(&num);//标记结果
Num = Num1;
int cnt = 0;
while (Num >= 10) {
Num /= 10;
cnt++;
}
_stprintf_s(s, _T("%d"), Num1);
settextcolor(WHITE);
settextstyle(50, 0, L"黑体");
outtextxy(255 - 25 * cnt, 150, s);
break;
}
}
getchar();
}
//判断距离
double dis(int x1, int y1, int x2, int y2) {
int inX = (x1 - x2) * (x1 - x2);
int inY = (y1 - y2) * (y1 - y2);
double r = 0.0;
r = sqrt(inX + inY);
return r;
}