计算器怎么用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语言编写简易的计算器相关推荐
- C语言编程>第六周 ① 编写一个录入函数:用来从键盘接收n个整型数并存放在一个整型数组中。 在主函数中调用该函数计算出这n个整数之和。
例题:编写一个录入函数:用来从键盘接收n个整型数并存放在一个整型数组中. 在主函数中调用该函数计算出这n个整数之和. 代码如下: /*代码分析:录入函数需要两个参数:一个参数是需要用来存储数字的数组, ...
- c语言编程模拟选举,C语言编程题精选
C语言编程题精选 C语言编程题精选 1. 编程实现对键盘输入的英文名句子进行加密.用加密方法为,当内容为英文字母时其在26字母中的其后三个字母代替该字母,若为其它字符时不变. 2. 编程实现将任意的十 ...
- 成都c语言编程培训机构,成都学c语言编程,成都学c语言编程去哪里,成都学c语言编程需要报培训班吗...
成都学c语言编程,成都学c语言编程去哪里,成都学c语言编程需要报培训班吗 首页 > 软件 > 成都学c语言编程 作者:镀金池 发布时间:2018-09-28 14:20 近似带有序布局 ...
- 罗定c语言,罗定学c语言编程,罗定学c语言编程培训,罗定学c语言编程一般怎么收费...
罗定学c语言编程,罗定学c语言编程培训,罗定学c语言编程一般怎么收费 首页 > 软件 > 罗定学c语言编程 作者:镀金池 发布时间:2018-10-04 23:40 依照c语言的法则, ...
- c语言编程技巧分析,C语言难点及编程技巧分析
摘要:近些年信息技术发展迅速,社会需要大量专业的计算机人才,C语言是学习计算机知识的专业理论课程,能够为以后的学习打下专业基础.但目前C语言学习受到各方面因素的影响,学习效果不是很理想,很多时候即使努 ...
- C语言编程>第五周 ⑤ 编写一个程序,从键盘输入X,Y,Z 3个数, 编写函数计算3个数的立方和并返回计算结果。
例题:编写一个程序,从键盘输入X,Y,Z 3个数, 编写函数计算3个数的立方和并返回计算结果. 第一种方法: 代码如下: #include <stdio.h> int abc(int,in ...
- 单片机c语言编程下载,单片机C语言编程.doc
单片机C语言编程.doc 单片机C语言编程指令格式 功能简述 字节数 周期 一.数据传送类指令 MOV A, Rn 寄存器送累加器 1 1 MOV Rn,A 累加器送寄存器 1 1 MOV A ,Ri ...
- Java编写简易控制台计算器
Java编写简易控制台计算器 主要需求与功能: 包含四个基本运算:加,减,乘,除 利用while循环和switch选择结构 包含两个基本操作数 输出结果后可选择退出或继续使用 import java. ...
- 如何下载c语言游戏,如何用C语言编写游戏.doc
<如何用C语言编写游戏.doc>由会员分享,可在线阅读,更多相关<如何用C语言编写游戏.doc(71页珍藏版)>请在皮匠网上搜索. 1.如何用C语言编写游戏网络游戏是常谈的话题 ...
最新文章
- MySQL 为什么我的MySQL会“抖一下“?
- SQL Server IF Exists 判断数据库对象是否存在的用法
- Height、offsetWidth、ClientHeight 区别
- visio2019安装教程
- 个人java学习心得总结
- [转载] 我的Android进阶之旅:经典的大牛博客推荐
- ConcurrentHashMap的使用场景
- 前度字符串转数组_java中的hashcode 前度刘郎
- 如何评价电影《西游记之大圣归来》?
- [033] 微信公众帐号开发教程第9篇-QQ表情的发送与接收
- 载入pytorch的预训练模型时遇到_pickle.UnpicklingError: unpickling stack underflow
- FTP如何设置用户名密码
- 两点之间的最短距离是?
- java的(PO,VO,TO,BO,DAO,POJO)类名包名解释
- 世界睁大眼睛关注中国春节
- spring中事务提交后再发MQ消息
- 数字校园php,利用PHP技术加强高校数字化校园的信息资源建设
- 通风橱尺寸及通风量(通风橱排风要求)
- TCOOP-M048-降压模块-78M05
- 小米手环能不能用计算机,小米手环2怎么用,功能有哪些?小米手环2简易使用教程...