C语言计算器设计实验报告

时间:2024.4.21

C语言计算器设计实验报告

班级:11661        姓名:            学号:38    

一、实验目的:利用C语言编写一个简单的计算器,并能正确运行+-*/四则运算。

二、实验内容:

1、             编写前分析;

1)、根据实验目的,要求键盘录入表达式,并运行后输出结果;由于键盘录入的表达式含数字和运算符,所以要选择用字符串数据类型输入。

2)、由于输入的是字符串,而只有数值类型的数据才能参与运算,所以得把字符(串)类型的数据转换为数值类型的数据。

3)、四则运算时,括号优先级高于乘除,乘除优先级高于加减,程序必须能正确判断其优先级才能得出正确的结果。

4)、为了保证运行结果的精确度需正确选择所用变量的数据类型。

2、利用所学知识进一步分析以上内容;

1)、利用gets函数输入表达式,例如:gets(calc);

2)、C语言中将字符类型数据转化成数值类型数据方法很多,该程序利用函数库stdlib.h中的atof函数来实现这一目的。同时注意主函数前加上预处理指令:#include<stdlib.h>

3)、为了能正确判断优先级,该程序利用函数间的多层嵌套,循环调用来实现;从优先级最高的括号开始判断,若有括号,再判断括号内部,若无括号判断是否为乘除,最后判断加减;括号内内容法方类似。具体判断方法在后面将以实例详细介绍。

4)、为了保证输出数据的精确度,该程序中函数f1()-f4()返回值均用double类型;用g格式符输出最终结果让输出结果简明而又能保证其精确度。

3、开始编程:

首先编写必要的预处理指令,声明必要的函数,定义必要的变量。

#include<stdio.h> (输入,输出函数需要该指令)

#include<stdlib.h> (atof函数需要该指令)

全局声明:

Double f1(); (用于存放最终输出结果);

Char calc[n]; (用于存放输入的表达式);

Int n; (用于标注clac中的各个元素);

编写主函数:

int main(void)

{

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

  gets(calc);(输入表达式)

  printf("原式=%g\n",f1());(程序将调用f1(),并输出f1()的结果)

  return(0);

}

由于四则运算先算出优先级最高的结果,并对同一优先级采用从左到右的顺序计算,所以最终的运算是对表达式进行加减运算。所以函数f1()必须对加减进行处理。所以编写如下:

double f1()

{

矩形标注: 表达式可能存在多个同级运算所以要利用循环语句。
  double t;

  t=f2();f2()用于临时表示乘除运算部分的结果)

  while((calc[n]=='+')||(calc[n]=='-'))

  {

    switch(calc[n])

    {

      case '+':n++,t=t+f2();break;

      case '-':n++,t=t-f2();break;

    }

  }

  return(t);

}

编写f2()用于计算乘除运算,同理要使用循环:

double f2()

{

  double t;

  t=f3();(用于临时表示括号内部的计算结果)

  while((calc[n]=='*')||(calc[n]=='/'))

  {

    switch(calc[n])

    {

      case '*':n++,t=t*f3();break;

      case '/':n++,t=t/f3();break;

    }

  }

  return(t);

}

编写f3():

double f3()

{

  char a[64];(用于转存变量calc

矩形标注: 用于判断是否是字符‘(’,若是则调用函数f1()并读取下一个字符。  int i=0;

  double t;

  if(calc[n]=='(')

  {

    n++,t=f1(),n++;

  }

  else if(f4())

  {

    while(f4())(判断是否满足f4(),若满足则依次将字符转存于函数a中)

    {

     a[i++]=calc[n++];

    }

    t=atof(a);(将字符串转换为浮点数)

  }

  return(t);

}

编写函数f4()

ouble f4()

{

  if((calc[n]>='0'&&calc[n]<='9')||(calc[n]=='.'))

  return(1);

}

4、运用举例:

下面以表达式:41+2*(5-3)为例详细分析程序的运行过程:

1输入字符串41+2*(5-3)2输出时遇到函数f1()3调用函数f1()4调用函数f2()5调用函数f3()6判断第一个字符不为’(‘,再判断第一个字符是否满足函数f4(),满足条件并判断第二个字符(满足),再判断第三个字符(不满足);将‘41’赋值个变量a,再将变量a转换成double类型赋值个变量t,将函数值41返回给该函数。-741返回调用处即f2()中的“t=f3()”,这时f2()返回值为41再返回f1()中的“t=2()”处。-8判断下一个字符‘+’(满足条件)执行到语句:case '+':n++,t=t+f2();9再次调用函数f2().f3().f4().最终将‘2’返回到t=f3();处。-10判断下一字符是否为*/,满足执行到:case '*':n++,t=t*f3();11再次调用f3(),执行到:n++,t=f1(),n++;---------,以下调用方法类似,不再一一列出.

5、程序分析:

1)、从函数f4()可知,输入函数calc的第一个字符必须为’.’’0’~’9’这十个字符,否则程序终止运行,并输出错误结果。

2)、从函数f3()可知,字符’(‘后面应紧跟数字,小数点或字符’(‘,否则出现(1)中同样的错误。例如:2+5*-5+8)不能算出正确值。

3)、该函数没有对字符’)’进行判断,一切为不满足函数f4()’+’’-‘’*’’/’的字符程序都将首先算出字符’(‘到该字符之间的表达式的结果;例如:2*6+4相当于

2*6+4)。6*21-9m相当于6*21-9)。

4)、只要输入规范的数学表达式,程序都会输出正确的结果。

三、实验总结:

通过该实验我们熟悉的掌握了函数:ifwhile,switch等函数的格式及功能。熟悉了函数间的调用过程及相关注意事项。

四、附录  源代码

#include<stdio.h>

#include<stdlib.h>

double f1(),f2(),f3(),f4();

char calc[64];

int n;

double f1()

{

  double t;

  t=f2();

  while((calc[n]=='+')||(calc[n]=='-'))

  {

    switch(calc[n])

    {

      case '+':n++,t=t+f2();break;

      case '-':n++,t=t-f2();break;

    }

  }

  return(t);

}

double f2()

{

  double t;

  t=f3();

  while((calc[n]=='*')||(calc[n]=='/'))

  {

    switch(calc[n])

    {

      case '*':n++,t=t*f3();break;

      case '/':n++,t=t/f3();break;

    }

  }

  return(t);

}

double f3()

{

  char a[64];

  int i=0;

  double t;

  if(calc[n]=='(')

  {

    n++,t=f1(),n++;

  }

  else if(f4())

  {

    while(f4())

    {

     a[i++]=calc[n++];

    }

    num[i]='\0';

    t=atof(a);

  }

  return(t);

}

double f4()

{

  if((calc[n]>='0'&&calc[n]<='9')||(calc[n]=='.'))

  return(1);

  else

           return(0);

}

int main(void)

{

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

  gets(calc);

  printf("原式=%g\n",f1());

  return(0);

}


第二篇:C语言计算器设计


C语言计算器设计 姓名:付强 学号:200806204122 班级:材料成型与控制技术0801 系别:机械工程系

C语言计算器设计

C语言程序设

设计思路:

用for语句控制程序整体的循环,使用后缀表达式和中缀表达式实现对运算符优先级的判断和运算。

中缀表达式:我们平时书写的表达式就是中缀表达式,形如(a+b)*(c+d),事实上是运算表达式形成的树的中序遍历,特点是用括号来描述优先级。

后缀表达式:也叫逆波兰表达式,事实上是算数表达式形成的树的后序遍历。中缀表达式(a+b)*(c+d)的后缀表达式是ab+cd+*,它的特点就是遇到运算符就立刻进行运算。

下面以一个实例来进行说明:2+(50-6*7)/2

1. 输入表达式2+(50-6*7)/2,先进行一次判断,如果为q则退出

整个程序,这里将表达式存入字符型数组a[ ]中,则a[ ]={'&','2','+','(','5','0','-','6','*','7',') ','/','2','\0'},然后调用calcu( )函数。

2. 第一次循环对a[1]进行判断,然后将2放入data[0].d1中,

nibo[1]=1;

第二次循环对a[2]进行判断,将'+'放入stack2[1]中; 第三次循环对a[3]进行判断,将'('放入stack2[2]中; 第四次循环对a[3]进行判断,先得出z=50,然后判断a[5]=0,则将'50'放入data[1].d1中,nibo[2]=2;

第五次循环对a[6]进行判断,将'-'放入stack2[3]中; 第六次循环对a[7]进行循环,将'6'放入data[2].d1中,nibo[3]=3;

第七次循环对a[8]进行判断,将'*'放入stack2[4]中; 第八次循环对a[9]进行判断,将'7'放入data[3].d1中,nibo[4]=4;

第九次循环对a[10]进行判断,将')'放入stack2[5]中; 第十次循环对a[11]进行判断,将'/'放入stack2[6]中; 第十一次循环对a[12]进行判断,然后将2放入data[4].d1中,nibo[5]=5;

第十二次循环对a[13]进行判断,为'\0',结束while循环,跳入下一个while。此时t1=6,t2=6。

具体数值如下:

nibo[++t1] Stack2[t2] data[top].d1 data[top].d2=cnt nibo[1]=1 Stack2[1]= '+' data[1].d1=2 data[1].d2=1 nibo[2]=2 Stack2[2]= '(' data[2].d1=50 data[2].d2=2 nibo[3]=3 Stack2[3]= '-' data[3].d1=6 data[3].d2=3 nibo[4]=4 Stack2[4]= '*' data[4].d1=7 data[4].d2=4 nibo[7]=5 Stack2[1]= '+' data[5].d1=2 data[5].d2=5 nibo[8]='\0' Stack2[2]= '/'

3. 进行转换,即:

nibo[8]=Stack2[2]=='+'

nibo[9]=Stack2[1]=='/'

nibo[10]='\0'

4. 进行逆波兰运算

while(j<=t1)

{ if(nibo[j]>='0'&&nibo[j]!='^'&&nibo[j]!='#')

{ for(i=1;i<=tree->top;i++)

{ if((int)(nibo[j]-'0')==tree->data[i].d2)

}

Stack3[++t3]=tree->data[m].d1;

}

else if(nibo[j]=='+')

{ Stack3[t3-1]=Stack3[t3-1]+Stack3[t3];

t3--;

}

else if(nibo[j]=='-')

{

}

else if(nibo[j]=='*')

{ } Stack3[t3-1]=Stack3[t3-1]*Stack3[t3]; t3--; Stack3[t3-1]=Stack3[t3-1]-Stack3[t3]; t3--; { } m=i; break;

else if(nibo[j]=='/')

{ Stack3[t3-1]=Stack3[t3-1]/Stack3[t3]; t3--;

}

else if(nibo[j]=='^')

{ Stack3[t3-1]=pow(Stack3[t3-1],Stack3[t3]); t3--;

}

else if(nibo[j]=='#')

{

j++;

} Stack3[t3]=sqrt(Stack3[t3]);}

5. 执行结果如图:

C语言计算器设计

源程序代码:

#include<stdio.h>

#include<math.h>

#include<malloc.h>

#define M 100

double calcu(char a[]);

void main()

{

{ //负责计算的函数 int e,f; for(e=0;e<=79;e++) printf("*");

printf(" 姓名:付强 学号:200806204122 日期:2010/5/20 指导教师:陶斌 \n");

for(f=0;f<=79;f++) printf("*");

printf("\n");

printf("说明: 输入表达式时无需输入 = 号 直接回车可输出答案 \n"); printf(" 开方用 # 表示,乘方用 ^ 表示。 退出请输入q (支持负数) \n\n\n");

} //图形输出函数 for(;;) {

printf("请输入您要计算的表达式:\n"); char x, a[M]; double outcome; int i=0; a[0]='$'; scanf("%c",&x); if(x=='q') break; while(x!='\n') { a[++i]=x; scanf("%c",&x); } a[i+1]='\0';

outcome=calcu(a);

} //调用calsu()来进行计if(outcome==10000000000000000000) ; else printf("=%lf",outcome); printf("\n\n\n");

}

double calcu(char a[])

{

//printf("t1 nibo[t1] nibo[5] cnt (t1+1) t2 Stack2[t2]\n"); /////***** int i=1,j,k,m,cnt=0,t1=0,t2=0,t3=0;

//建立2数组 stack2. stack3用于 char nibo[50],Stack2[50];

存放算式中的数字和运算符,进行压栈

double x,n,l,z=0,Stack3[50]; typedef struct { double d1; int d2;

}dd; typedef struct

成员

{

int top; //建立结构体stack1,其中有两个dd data[50]; }Stack1; Stack1 *tree; //将stack1 指向tree的指针,在

动态内存中开辟一个stack大小的内存,并将首地址传给tree指针 tree=(Stack1 *)malloc(sizeof(Stack1));

tree->top=0;

if(a[1]=='\0'||(a[1]>='A'&&a[1]<='z')||a[1]==' ')

检查,如果出现错误则会出现提示

{ printf(" //将算式进行简单的!!!!!请输入正确的表达式!!!!!"); return(9999999999999999999);

}

else

{

while(a[i]!='\0')

字和运算符进行识别,并压入对应的栈的位置

{

if(a[i]>='0'&&a[i]<='9')

{ z=0;

j=i+1;

while(a[j]>='0'&&a[j]<='9')

{j++;}

j--;

for(k=i;k<=j;k++)

{

z=z*10+a[k]-'0';

}

j=j+1;

x=z;

if(a[j]=='.')

{

l=1;

i=j+1;

j=i+1;

while(a[j]>='0'&&a[j]<='9')

{j++;}

j--;

for(k=i;k<=j;k++)

{

n=pow(0.1,l);

l=l+1;

x=x+n*(a[k]-'0');

}

i=j+1;

}

else i=j;

tree->data[++tree->top].d1=x; 这个while循环将表达式中的数 //

tree->data[tree->top].d2=++cnt; nibo[++t1]='0'+tree->data[tree->top].d2; nibo[t1+1]='\0'; } else if(a[i]=='(') { Stack2[++t2]=a[i]; // 用tree指向的内存空间对算是的数字和运算符进行缓存,并将运算符放到后缀表达式nibo[]中

i++;

} else if(a[i]==')') { } j=t2; while(Stack2[j]!='(') { } nibo[++t1]=Stack2[j]; nibo[t1+1]='\0'; j--; t2=j-1; i++; else if(a[i]=='+') { while(t2>0&&Stack2[t2]!='(') { nibo[++t1]=Stack2[t2]; nibo[t1+1]='\0'; t2--; } Stack2[++t2]=a[i]; i++; } else if(a[i]=='-') { if(a[i-1]=='$') { } { a[i-1]='0'; a[i-2]='('; a[0]='0'; i=0; else if(a[i-1]=='(')

i=i-2; t2--; } else { } while(t2>0&&Stack2[t2]!='(') { } nibo[++t1]=Stack2[t2]; nibo[t1+1]='\0'; t2--; Stack2[++t2]=a[i]; i++; } else if(a[i]=='*'||a[i]=='/')

{ //判断是否为乘除,则放到nibo[]

while(Stack2[t2]=='*'||Stack2[t2]=='/'||Stack2[t2]=='^'||Stack2[t2]=='#') } { } nibo[++t1]=Stack2[t2]; nibo[t1+1]='\0'; t2--; Stack2[++t2]=a[i]; i++; else if(a[i]=='^'||a[i]=='#') { } while(Stack2[t2]=='^'||Stack2[t2]=='#') { nibo[++t1]=Stack2[t2]; nibo[t1+1]='\0'; t2--; } Stack2[++t2]=a[i]; i++; //printf("%d %c %d %d %d %d %c \n /////***** //printf("%c\n",nibo[5]);////////// } ",t1,nibo[t1],nibo[5],cnt,(t1+1),t2,Stack2[t2]);

while(t2>0)

{

} nibo[++t1]=Stack2[t2]; nibo[t1+1]='\0'; t2--; //printf(" %d %c\n",t1,nibo[t1]);

j=1;t3=0;

while(j<=t1)

{ //用stack3来存放运算结果,并返回到主函数为最终的值 if(nibo[j]>='0'&&nibo[j]!='^'&&nibo[j]!='#') //对后缀表达式进行出栈排列

{

}

//若nibo[]中遇到运for(i=1;i<=tree->top;i++) { if((int)(nibo[j]-'0')==tree->data[i].d2) { m=i; break; } } Stack3[++t3]=tree->data[m].d1; else if(nibo[j]=='+')

算符,则立刻进行预算,

{ } Stack3[t3-1]=Stack3[t3-1]+Stack3[t3]; t3--;

else if(nibo[j]=='-') { Stack3[t3-1]=Stack3[t3-1]-Stack3[t3]; t3--; } else if(nibo[j]=='*') { } Stack3[t3-1]=Stack3[t3-1]*Stack3[t3]; t3--;

else if(nibo[j]=='/') { } Stack3[t3-1]=Stack3[t3-1]/Stack3[t3]; t3--; else if(nibo[j]=='^') { Stack3[t3-1]=pow(Stack3[t3-1],Stack3[t3]); t3--; } else if(nibo[j]=='#') { } Stack3[t3]=sqrt(Stack3[t3]); j++;

}

return Stack3[t3]; }

}

更多相关推荐:
计数器实验报告

实验4计数器及其应用一实验目的1学习用集成触发器构成计数器的方法2掌握中规模集成计数器的使用及功能测试方法二实验原理计数器是一个用以实现计数功能的时序部件它不仅可用来计脉冲数还常用作数字系统的定时分频和执行数字...

简单的计算器实验报告

HUNANUNIVERSITY程序设计训练简单的计算器报告学生姓名田博鑫学生学号专业班级指导老师20xx年6月16日至20xx年7月10日1吴蓉晖1程序设计目的和要求目的此次程序设计的目的主要是为了我们能更好的...

计算器实验报告 (1)

HTML网页实验报告院系计算机控制与工程学院班级计1241学号姓名完成日期1一实验名称设计一个网页计算器二需求分析计算器是日常生活中十分便捷有效的工具能实现加减乘除开方求倒数等简单运算的工具要实现计算功能可以用...

计算器实验报告

目录一系统开发的背景1二系统分析与设计1一二计算器的主要功能1系统模块结构设计1三系统的设计与实现2一二计算器的初始界面2一般计算3三解一元二次方程5四计算银行本利和5四系统测试7一二测试主函数MAIN7测试一...

C#计算器实验报告

C计算器实验报告班级学号20xx13432姓名蔡启林一实验目的和要求设计一个简单计算器具有一般计算功能能进行基本的加减乘除运算还具有求根号倒数等功能特点是能进行不同进制的运算和不同进制间的转换主要的工作主要是操...

计算器实验报告

计科系实验报告单

模拟计算器实验报告

课程设计报告课程设计题目:模拟机算器程序学生姓名:专业:网络工程班级:指导教师:20XX年11月27日东华理工大学课程设计评分表学生姓名:XXX班级:XXX学号:21课程设计题目:模拟机算器程序目录一.课程设计…

c#实验报告计算器设计

实验2计算器设计文档姓名梁姣学号07220xx1班级计本071日期20xx1009实验目的和要求1设计背景设计拥有简单的计算功能方便计算简单的计算题方便用户的使用2设计功能具有一般计算功能能进行基本的加减乘除运...

C++实现计算器实验报告

实验报告完成日期20xx年10月27日实验题目完整计算器需求分析请实现一个只包含加减乘除以及括号运算的简单计算器输入格式是正确的不需要判断注意式子中可能会出现负数以及多余的空格操作数也可能是多位数和小数概要设计...

基于MFC的科学计算器课程设计实验报告

浙江工商大学C课程设计报告课程设计实验报告题目学院专业班级课程名称学号学生姓名指导教师成绩二一三年一月1浙江工商大学C课程设计报告目录1概述11课程设计目的12课程设计内容13课程设计思想2系统需求分析21系统...

课程设计报告——计算器

北京化工大学20xx20xx课程设计报告计算机科学与技术计算器程序的设计与实现数据结构课程设计班级计科1001北京化工大学信息科学与技术学院计算机科学与技术专业北京化工大学20xx20xx课程设计报告计算机科学...

c++计算器实验报告

简单计算器学号20xx21176051姓名周吉祥实验目的模仿日常生活中所用的计算器自行设计一个简单的计算器程序实现简单的计算功能实验内容1体系设计程序是一个简单的计算器能正确输入数据能实现加减乘除等算术运算运算...

计算器实验报告(47篇)