失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 计算器怎么用c语言编程 如何用C语言编写简易的计算器

计算器怎么用c语言编程 如何用C语言编写简易的计算器

时间:2018-10-27 04:33:37

相关推荐

计算器怎么用c语言编程 如何用C语言编写简易的计算器

表达式计算建议看一下《数据结构》,先转换为逆波兰表达式,然后再计算。

当然用字符串匹配也是可以的,但是这样复杂度会比较高,

匹配最里面的括号有一个方法就是寻找第一个右括号,和这个右括号对应的左括号合起来就是最里面的括号。

当然我给你一个逆波兰表达式的代码吧,可以解决你的问题,有点长,300多行:

#include

#include

#include

#include

#define ElemItem Item

#define SUCCEED 1

#define ERROR 0

#define MAXLENGTH 20

struct Item{

int type; //0表示单目运算符,1表示双目运算符,2表示数字

double num; //如果是数字就保存在这里

char oper[MAXLENGTH]; //如果是运算符就保存在这里

}nullItem;

typedef struct SNode{

ElemItem data;

SNode *next;

}*Stack;

struct QNode{

ElemItem data;

QNode *next;

};

struct Queue{

QNode *front;

QNode *rear;

};

void initStack(Stack *s){

*s = NULL;

}

void push(Stack *s, ElemItem e){

SNode *p = (SNode*)malloc(sizeof(SNode));

p->data = e;

p->next = *s;

*s = p;

}

int pop(Stack *s, ElemItem *e = NULL){

if(*s == NULL){

return ERROR;

}

if(e != NULL){

*e = (*s)->data;

}

SNode *p = *s;

*s = (*s)->next;

free(p);

return SUCCEED;

}

ElemItem getSData(Stack s){

if(s == NULL){

return nullItem;

}

return s->data;

}

void initQueue(Queue *q){

q->front = NULL;

q->rear = NULL;

}

void in(Queue *q, ElemItem e){

QNode* p = (QNode*)malloc(sizeof(QNode));

p->data = e;

p->next = NULL;

if(q->rear != NULL){

q->rear->next = p;

}

q->rear = p;

if(q->front == NULL){

q->front = p;

}

}

int out(Queue *q, ElemItem *e){

if(q->front == NULL){

return ERROR;

}

*e = q->front->data;

QNode *p = q->front;

q->front = q->front->next;

free(p);

return SUCCEED;

}

ElemItem getQData(Queue q){

if(q.front == NULL){

return nullItem;

}

return q.front->data;

}

int getPriority(char *a){

if(strcmp(a, "+") == 0 || strcmp(a, "-") == 0)

return 1;

if(strcmp(a, "*") == 0 || strcmp(a, "/") == 0)

return 2;

if(strcmp(a, "^") == 0)

return 3;

if(strcmp(a, "sin") == 0 || strcmp(a, "cos") == 0 || strcmp(a, "tan") == 0 \

|| strcmp(a, "ln") == 0 || strcmp(a, "exp") == 0 \

|| strcmp(a, "arcsin") == 0 || strcmp(a, "arccos") == 0 || strcmp(a, "arctan") == 0)

return 4;

return -1;

}

int getCombination(char *a){ //1表示左结合,0表示右结合

if(strcmp(a, "+") == 0 || strcmp(a, "-") == 0 || strcmp(a, "*") == 0 || strcmp(a, "/") == 0 || strcmp(a, "^") == 0)

return 1;

if(strcmp(a, "sin") == 0 || strcmp(a, "cos") == 0 || strcmp(a, "tan") == 0 \

|| strcmp(a, "ln") == 0 || strcmp(a, "exp") == 0 \

|| strcmp(a, "arcsin") == 0 || strcmp(a, "arccos") == 0 || strcmp(a, "arctan") == 0)

return 0;

return -1;

}

int getOrder(char *a){ //0表示单目,1表示双目

if(strcmp(a, "+") == 0 || strcmp(a, "-") == 0 || strcmp(a, "*") == 0 || strcmp(a, "/") == 0 || strcmp(a, "^") == 0)

return 1;

if(strcmp(a, "sin") == 0 || strcmp(a, "cos") == 0 || strcmp(a, "tan") == 0 \

|| strcmp(a, "ln") == 0 || strcmp(a, "exp") == 0 \

|| strcmp(a, "arcsin") == 0 || strcmp(a, "arccos") == 0 || strcmp(a, "arctan") == 0)

return 0;

return -1;

}

double getResult0(char *oper, double a1){

if(strcmp(oper, "+") == 0)

return a1;

if(strcmp(oper, "-") == 0)

return -a1;

if(strcmp(oper, "sin") == 0)

return sin(a1);

if(strcmp(oper, "cos") == 0)

return cos(a1);

if(strcmp(oper, "tan") == 0)

return tan(a1);

if(strcmp(oper, "ln") == 0)

return log(a1);

if(strcmp(oper, "exp") == 0)

return exp(a1);

if(strcmp(oper, "arcsin") == 0)

return asin(a1);

if(strcmp(oper, "arccos") == 0)

return acos(a1);

if(strcmp(oper, "arctan") == 0)

return atan(a1);

return 0;

}

double getResult1(char *oper, double a1, double a2){

if(strcmp(oper, "+") == 0)

return a1+a2;

if(strcmp(oper, "-") == 0)

return a1-a2;

if(strcmp(oper, "*") == 0)

return a1*a2;

if(strcmp(oper, "/") == 0)

return a1/a2;

if(strcmp(oper, "^") == 0)

return pow(a1,a2);

return 0;

}

double calculate(char *expression){

//对表达式信息初步读取

int length = strlen(expression);

Queue firstExp;

initQueue(&firstExp);

int flag = -1; //0表示数字,1表示运算符,2表示函数

char tmp[MAXLENGTH] = {'\0'};

for(int i=0; i

if(expression[i] != ' '){

if((expression[i] >= '0' && expression[i] <= '9') || expression[i] == '.'){

if(flag == 1 || flag == 2){

Item item;

item.type = getOrder(tmp);

strcpy(item.oper, tmp);

in(&firstExp, item);

flag = 0;

tmp[0] = '\0';

}

if(flag == -1){

flag = 0;

}

}else{

if(expression[i] >= 'a' && expression[i] <= 'z'){

if(flag == 0){

Item item;

item.type = 2;

item.num = strtod(tmp, NULL);

in(&firstExp, item);

flag = 2;

tmp[0] = '\0';

}else if(flag == 1){

Item item;

item.type = getOrder(tmp);

strcpy(item.oper, tmp);

in(&firstExp, item);

flag = 2;

tmp[0] = '\0';

}else if(flag == 2 && getOrder(tmp) != -1){

Item item;

item.type = getOrder(tmp);

strcpy(item.oper, tmp);

in(&firstExp, item);

tmp[0] = '\0';

}

if(flag == -1){

flag = 2;

}

}else{

if(flag == 0){

Item item;

item.type = 2;

item.num = strtod(tmp, NULL);

in(&firstExp, item);

flag = 1;

tmp[0] = '\0';

}else if(flag == 2){

Item item;

item.type = getOrder(tmp);

strcpy(item.oper, tmp);

in(&firstExp, item);

flag = 1;

tmp[0] = '\0';

}else if(flag == 1){

Item item;

item.type = getOrder(tmp);

strcpy(item.oper, tmp);

in(&firstExp, item);

tmp[0] = '\0';

}

if(flag == -1){

flag = 1;

}

}

}

int l = strlen(tmp);

if(l < MAXLENGTH-1){

tmp[l] = expression[i];

tmp[l+1] = '\0';

}

//printf("first runing\n");

}

}

if(flag == 0){

Item item;

item.type = 2;

item.num = strtod(tmp, NULL);

in(&firstExp, item);

}else{

Item item;

item.type = 1;

strcpy(item.oper, tmp);

in(&firstExp, item);

}

tmp[0] = '\0';

//printf("first end\n");

/*Item i;

while(out(&firstExp, &i)){

if(i.type == 2){

printf("%lf\n", i.num);

}else{

printf("%s\n", i.oper);

}

}*/

//生成后缀表达式

int frontHasNum = 0; //最开始有无数字,0表示无数字,1表示有数字,如果最开始无数字,则第一个运算符降为单目运算符

Stack operStack;

initStack(&operStack);

Queue secondExp;

initQueue(&secondExp);

Item firstItem;

while(out(&firstExp, &firstItem)){

if(firstItem.type == 2){

frontHasNum = 1;

in(&secondExp, firstItem);

}else{

if(strcmp(firstItem.oper, "(") == 0){

frontHasNum = 0;

push(&operStack, firstItem);

}else if(strcmp(firstItem.oper, ")") == 0){

frontHasNum = 1;

Item t;

while(strcmp(getSData(operStack).oper, "(") != 0){

if(!pop(&operStack, &t))

break;

in(&secondExp, t);

//printf("second 1 while\n");

}

pop(&operStack);

}else{

Item t;

while((getPriority(firstItem.oper) < getPriority(getSData(operStack).oper)) \

|| (getPriority(firstItem.oper)==getPriority(getSData(operStack).oper) && getCombination(getSData(operStack).oper)==1)){

if(!pop(&operStack, &t))

break;

in(&secondExp, t);

//printf("second 2 while\n");

}

if(frontHasNum == 0){

frontHasNum = 1;

firstItem.type = 0;

}

push(&operStack, firstItem);

}

}

//printf("second runing\n");

}

while(pop(&operStack, &firstItem)){

in(&secondExp, firstItem);

//printf("second in runing\n");

}

//printf("second end\n");

/*Item i2;

while(out(&secondExp, &i2)){

if(i2.type == 2){

printf("%lf\n", i2.num);

}else{

printf("%s\n", i2.oper);

}

}*/

//计算

Stack startCalculate;

initStack(&startCalculate);

Item startItem;

while(out(&secondExp, &startItem)){

if(startItem.type == 2){

push(&startCalculate, startItem);

}else{

if(startItem.type == 0){

Item a;

pop(&startCalculate, &a);

a.num = getResult0(startItem.oper, a.num);

push(&startCalculate, a);

}else if(startItem.type == 1){

Item a1,a2;

pop(&startCalculate, &a2);

pop(&startCalculate, &a1);

Item a;

a.type = 2;

a.num = getResult1(startItem.oper, a1.num, a2.num);

push(&startCalculate, a);

}

}

//printf("calculating\n");

}

Item result;

pop(&startCalculate, &result);

return result.num;

}

int main(int argc, char *argv[]){

char exp[200] = {'\0'};

if(argc != 2){

printf("输入表达式:\n");

//scanf("%s", exp);

gets(exp);

}else{

strcpy(exp, argv[1]);

}

printf("计算结果为:%lf\n", calculate(exp));

return 0;

}

运行后直接输入算式就可以了。

如果觉得《计算器怎么用c语言编程 如何用C语言编写简易的计算器》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。