自己用纯C写的一个简单的表达式科学计算器,欢迎大家观阅。


<p style="color:red; font-size: 30px;">欢迎光临</p>
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "math.h"


#define DIGIT 0 //操作数
#define OPERATION 1 //操作符
#define END -1 //结束
#define MAX 1000
#define SIN 115
#define ASIN 120
#define COS 99
#define ACOS 104
#define TAN 116
#define ATAN 121
#define SQRT 113
#define LOG 108
#define LN 109
#define PI 3.1415926
#define E 2.71828 
typedef double DATA_DIGIT;


int priority[255];
int IsNegetive = 0;
int IsCorrect = 1;
int AngleSystem = 0;
int Decimal = 2;


typedef struct
{
int operater;
DATA_DIGIT dat;
int type;
}Data;


typedef struct
{
Data stack[MAX];
int top;
}Stack;


Data Pop (Stack* s)
{
return s->stack[--s->top];
}


Data Top (Stack* s)
{
return s->stack[(s->top)-1];
}


void Push (Stack* s, DATA_DIGIT dat, int type)
{
if (type == DIGIT)
s->stack[s->top].dat = dat;
else
s->stack[s->top].operater = (int)dat;
s->stack[s->top++].type = type;
}


int isEmpty (Stack* s)
{
return 0 == s->top;
}
/结构及栈操作
void InputArr(DATA_DIGIT dat, int type, Data* arr, int arrCount)
{
if (type == DIGIT)
arr[arrCount].dat = dat;
else
arr[arrCount].operater = (int)dat;
arr[arrCount].type = type;
}
//阶乘计算
int Fac(int i)
{
int sum = 1;
while (i >= 2)
sum *= i--;
return sum;
}
//后缀
void Suffixation (char* string, Stack* psuffix, Data* Arr)
{
char* str = string;
DATA_DIGIT SumDigit;
int datCount = 0;
while (*str != '\0')
{
if (*str == ' ')
{
str++;
continue;
}
else if (isdigit(*str)) //操作数入栈
{
sscanf(str, "%lf", &SumDigit);
while (isdigit(*str) || *str == '.')
str++;
// printf("SUM = %lf\n", SumDigit);
if (IsNegetive) //负数处理
{
SumDigit = 0-SumDigit;
IsNegetive = 0;
}
InputArr (SumDigit, DIGIT, Arr, datCount++);
}
else if (*str == '+' || *str == '-' || *str == '*' || *str == '/' || *str == '^' || *str == '!' || *str == '%')//操作符入口
{
if (*str == '-' && (str == string || *(str-1) == '(')) //判断负数
{
IsNegetive = 1;
str++;
continue;
}
if (isEmpty(psuffix))
NULL;
else if (*str == '^') //对^操作等计算前面的操作符
{
while (!isEmpty(psuffix) && Top(psuffix).operater != '(' && priority[*str] < priority[Top(psuffix).operater])
{
InputArr (Pop(psuffix).operater, OPERATION, Arr, datCount++);
}
}
else //对+-*/!%操作等计算前面的操作符
{
while (!isEmpty(psuffix) && Top(psuffix).operater != '(' && priority[*str] <= priority[Top(psuffix).operater])
{
InputArr (Pop(psuffix).operater, OPERATION, Arr, datCount++);
}
}
Push (psuffix, *str, OPERATION);
str++;
}
else if (*str == '(')
{
Push (psuffix, *str, OPERATION);
str++;
}
else if (*str == ')')
{
if (isEmpty(psuffix))
{
IsCorrect = 0;
printf("输入错误,请重新输入\n");
return;
}
while (Top(psuffix).operater != '(')
{
InputArr (Pop(psuffix).operater, OPERATION, Arr, datCount++);
}
Pop(psuffix);
str++;
}
else if (*str == 'p' && *(str+1) == 'i')
{
InputArr (PI, DIGIT, Arr, datCount++);
str += 2;
}
else if (*str == 'l' && *(str+1) == 'o' && *(str+2) == 'g') //log
{
Push (psuffix, LOG, OPERATION);
str += 3;
}
else if (*str == 'l' && *(str+1) == 'n') //ln
{
Push (psuffix, LN, OPERATION);
str += 2;
}
else if (*str == 's' && *(str+1) == 'i' && *(str+2) == 'n') //sin
{
Push (psuffix, SIN, OPERATION);
str += 3;
}
else if (*str == 'c' && *(str+1) == 'o' && *(str+2) == 's') //cos
{
Push (psuffix, COS, OPERATION);
str += 3;
}
else if (*str == 't' && *(str+1) == 'a' && *(str+2) == 'n') //tan
{
Push (psuffix, TAN, OPERATION);
str += 3;
}
else if (*str == 'a' && *(str+1) == 's' && *(str+2) == 'i' && *(str+3) == 'n') //asin
{
Push (psuffix, ASIN, OPERATION);
str += 4;
}
else if (*str == 'a' && *(str+1) == 'c' && *(str+2) == 'o' && *(str+3) == 'n') //acos
{
Push (psuffix, ACOS, OPERATION);
str += 4;
}
else if (*str == 'a' && *(str+1) == 't' && *(str+2) == 'a' && *(str+3) == 'n') //atan
{
Push (psuffix, ATAN, OPERATION);
str += 4;
}
else if (*str == 's' && *(str+1) == 'q' && *(str+2) == 'r' && *(str+3) == 't') //sqrt
{
Push (psuffix, SQRT, OPERATION);
str += 4;
}
else if (*str == 'e')
{
InputArr (E, DIGIT, Arr, datCount++);
str++;
}
else
{
printf("输入不可知%c\n", *str++);
IsCorrect = 0;
return;
}
}


while (!isEmpty (psuffix))
{
if (Top(psuffix).operater == '(' || Top(psuffix).operater == ')')
{
printf("括弧不对称\n");
IsCorrect = 0;
return;
}
InputArr (Pop(psuffix).operater, OPERATION, Arr, datCount++);
}
Arr[datCount].type = END;
}


//后缀式的计算
DATA_DIGIT Calculate (Data* arr, Stack* psuffix)
{
if (!IsCorrect)
return NULL;
Data* temp = arr;
DATA_DIGIT num_a, num_b, num_c;
while (temp->type != END)
{
if (temp->type == DIGIT)
Push (psuffix, temp->dat, DIGIT);
else if (temp->type == OPERATION)
{
if (temp->operater == '!' || temp->operater == SIN || temp->operater == COS || temp->operater == TAN || temp->operater == SQRT || temp->operater == ASIN || temp->operater == ACOS || temp->operater == ATAN || temp->operater == LN)
//需要一个操作数的操作符!
{
if (!isEmpty(psuffix))
num_a = Pop(psuffix).dat;
else
{
IsCorrect = 0;
printf("输入错误,请重新输入\n");
return 0;
}
if (temp->operater == '!')
{
num_c = Fac((int)num_a);
continue;
}
else if (temp->operater == SQRT)
{
num_c = sqrt(num_a);
}
else if (temp->operater == LN)
{
num_c = log(num_a);
}
else if (temp->operater == SIN || temp->operater == COS || temp->operater == TAN)
{
if (AngleSystem == 0)
num_a = num_a*(PI/180); //角度制换算
if (temp->operater == SIN)
num_c = sin(num_a);
else if (temp->operater == COS)
num_c = cos(num_a);
else if (temp->operater == TAN)
num_c = tan(num_a);
}
else if (temp->operater == ASIN || temp->operater == ACOS || temp->operater == ATAN)
{
if (temp->operater == ASIN)
num_c = asin(num_a);
else if (temp->operater == ACOS)
num_c = acos(num_a);
else if (temp->operater == ATAN)
num_c = atan(num_a);
if (AngleSystem == 0)
num_c = num_c*(180/PI); //角度制换算
}
// printf("%lf%c = %lf\n", num_a, temp->operater, num_c);
}
else //需要两个操作数的操作符+-*/^
{
//num_a 为左操作数 num_b 为右操作数
if (!isEmpty(psuffix))
num_b = Pop(psuffix).dat;
else
{
IsCorrect = 0;
printf("输入错误,请重新输入\n");
return 0;
}
if (!isEmpty(psuffix))
num_a = Pop(psuffix).dat;
else
{
IsCorrect = 0;
printf("输入错误,请重新输入\n");
return 0;
}
if (temp->operater == '+')
num_c = num_a + num_b;
else if (temp->operater == '-')
num_c = num_a - num_b;
else if (temp->operater == '*')
num_c = num_a * num_b;
else if (temp->operater == '/')
num_c = num_a / num_b;
else if (temp->operater == '%')
num_c = (int)num_a % (int)num_b;
else if (temp->operater == '^')
{
num_c = 1;
int i = (int)num_b;
while (i--)
num_c *= num_a;
}
else if (temp->operater == LOG)
{
num_c = log(num_b) / log(num_a);
}
else
printf("Wrong %c\n", temp->dat);
// printf("%lf%c%lf=%lf\n", num_a, temp->operater, num_b, num_c);
}
Push (psuffix, num_c, DIGIT);
}
temp++;
}
return Pop(psuffix).dat;
}


int main(int argc, char* argv[])
{
printf("本计算器支持加减乘除,负数,括弧,指数,除余,阶乘\n开平方跟(sqrt), 对数(如(3)log(9) = 2, ln(e) = 1)\n");
printf("反三角函数(asin,acos,atan)\n");
printf("三角函数(默认角度制,输入\"_AngleSystem\"更换弧度制), 更换小数位数输入\"_Decimal\"\n");
printf("*******************************************************************************\n\n\n");


char input[MAX];
// strcmp(input, "-1.2^3+(-2.23)*(68/6.1-31*5.5/(3+3)+(1-9*(6-3))*55+22-8)*(2*6-5!)+tan(1)*sin(1)+cos(1)");
priority['+'] = priority['-'] = 1;
priority['*'] = priority['/'] = priority['%'] = 5;
priority['('] = priority[')'] = 10;
priority['^'] = 15;
priority['!'] = 20;
priority[SIN] = priority[COS] = priority[TAN] = priority[SQRT] = 50;
priority[ASIN] = priority[ACOS] = priority[ATAN] = 50;
priority[LOG] = priority[LN] = 60;
// gets(input);
Stack suffix;
Data calArr[MAX], *temp;
while (gets(input), strcmp(input, "END") != 0)
{
if (strcmp(input, "_AngleSystem") == 0)
{
AngleSystem = 1 - AngleSystem;
printf("已更换为%s\n\n", AngleSystem ? "弧度制" : "角度制");
continue;
}
else if (strcmp(input, "_Decimal") == 0)
{
printf("输入小数保留位数(输入0为默认值):");
while (scanf("%d", &Decimal), Decimal < 0 || Decimal >= 16)
printf("输入错误,请保证小数位为1-16位\n\n");
if (!Decimal)
Decimal = 2;
continue;
}
IsNegetive = suffix.top = 0;
IsCorrect = 1;
//
Suffixation (input, &suffix, calArr);

temp = calArr;
/* if (IsCorrect)
while (temp->type != END)
{
if (temp->type == DIGIT)
printf("%lf ", temp->dat);
else
printf("%c ", temp->operater);
temp++;
}
printf("\n");
*/
double i = Calculate (calArr, &suffix);
if (!isEmpty(&suffix))
{
IsCorrect = 0;
printf("输入错误,请重新输入\n");
}
if (IsCorrect)
printf("%.*lf\n", Decimal, i);
//
// while (!isEmpty(&suffix))
// printf("Wrong!  %c %lf\n", Top(&suffix).operater, Pop(&suffix).dat);
printf("*******************************************************************************\n");

}
return 0;
}

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值