C语言实现计算器

计算器

主要功能

- 实现表达式计算('+' '-' '*' '/' '%' '√' '(' ')')
- 界面
- 多位数运算
#include <stdio.h>
#include <graphics.h>
#include <conio.h>
#include <time.h>
#include<math.h>
#include <stdlib.h>


#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));
	if (p == NULL)
	{
		return ERROR;
	}
	p->data = e;
	p->next = S->top;
	S->top = p;
	S->count++;

	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);
	// 设置背景为深灰色
	setbkcolor(RGB(51, 51, 51));
	int c;
	for (int y = 0; y < 20; y++) {
		setcolor(RGB(51, 51, 51));
		line(0, y, 400, y);
	}
	//设置文本颜色
	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);
	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;
	ExMessage m;
	int temp = 0, k = 255, go = 0;
	//设置文本颜色
	settextcolor(WHITE);
	//设置文本样式
	settextstyle(40, 0, L"黑体");//字体的宽+字体的高+字体样式
	while (go == 0)
	{
		m = getmessage(EM_MOUSE | EM_KEY);
		switch (m.message)
		{
		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++)
				{
					outtextxy(k - 30 * (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 = 20; y < 200; y++) {
				setcolor(BLACK);
				line(0, y, 300, y);
			}
			TCHAR s[10];
			_stprintf_s(s, _T("%d"), Pop(&num));
            settextcolor(WHITE);
			outtextxy(255, 50, 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;
}
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值